2. JS組件概念--從零起步實現基於Html5的WEB設計器Jquery插件(含源碼)


上文提到計划開發的一個支持用戶擴展的開放設計器平台,它基於Html5,純JS,考慮到方便用戶進行引用和擴展,定義成一個單獨的js組件的形式,本文重點就如何設計JS組件做一個詳細說明。

設計組件前,我們先要思考組件如何初始化,首先既然是圖形化的,那就必須用到HTML5的Canvas元素,開發人員先在頁面上建一個canvas作為設計器組件的宿主,在組件$(function(){...})執行時,調用組件的初始化方法(init),然后依據初始化顯示的內容再在畫布上面進行渲染(render)。

第一種組件寫法:全局Javascript 對象法

我們知道Javascript里所有對象定義是以大括號來定義的{}的,那我們visualDesigner.1.0可以定義為:

var visualDesigner = {
    mode:1, //設計時/運行時
    container: "", //容器id
    content: {}, //內容
    init: function (config) {
        this.container = config.id;
        this.mode = config.runMode;
        if (config.content)
            this.content = JSON.parse(config.content); //默認初始化時加載的內容
        this.render();
    },
    render: function () {
        if (this.content && this.content.text)
        {
            $("#" + this.container).html(this.content.text);
        }
    },
    save: function () {
        //保存content
    },
    open: function (content) {
        //通常保存到本地或數據庫時以字符串形式存在的,故需轉成對象。
        if (content) 
            this.content = JSON.parse(content);
        else
            console.log("open方法打開的content不能為空");
        this.render();
    }
}
var runMode = { designTime: 1, runTime: 2 };

可以這樣調用:

    $(function () {
        visualDesigner.init({ id: "designView", runMode: runMode.designTime, content: "{\"text\":\"hello world\"}" });
    })

這種方法最大的問題是所有的屬性或方法都是公有的,如果代碼方法和屬性比較多時,比較難以維護,面向對象設計時一個重要的原則是開放-封閉原則,而這樣的設計完全違背了這個原則。

第二種組件寫法:JQuery組件寫法

jquery組件的寫法第一種是通過標記的形式,比如在容器上標記 data-toggle=“designerView",然后在document.ready時組件函數自動調用初始化(init)

另一種寫法是通過在組件里document.ready或等價的(fucntion(){...})(jQuery)函數里手動調用對象的init初始化,一些jquery插件如bootstrap的組件、jquery.validator等都是基於這種方法。

    $(function () {
        $("#designView").visualDesigner("init", { model: runMode.designTime, content: "{\"text\":\"hello world\"}" });
    })

以下為visualDesigner.2.0定義:

+function ($) {
    "use strict";

    // VisualDesigner 公共類定義
    // ===============================
    var VisualDesigner = function (element, options) {
        this.init(element, options)
    }
    if (!paper) throw new Error('VisualDesigner requires paper.js')
    VisualDesigner.DEFAULTS = $.extend({},{
        content: '',
        color: "red",
        font_color: "yellow",
        opacity:0.5
    })
    VisualDesigner.prototype.init = function (element, options) {
        this.enabled = true
        this.$element = $(element)
        this.htmlCanvas = element instanceof jQuery? element[0] : element;
        this.options = this.getOptions(options)
        //初始化設計器代碼
        this.canvas = paper.setup(this.htmlCanvas.id);
        //this.canvas.project.view.viewSize = new paper.Size(this.options.width, this.options.height);
        this.options = $.extend({ 'raster': 0 }, this.options || {});
        this.originalPoint = this.canvas.project.view.center;//保留中心
        this.centerPoint = { x: 0, y: 0 };

        this.group = new paper.Group();
        var fillColor = this.options.color;
        var fontColor = this.options.font_color;
        var rect = new paper.Path.Rectangle({
            point: [50,50],
            size: [100,100],
            radius: 5,
            strokeWidth: 1,
            strokeColor: this.options.color,
            fillColor: this.options.color,
            opacity: this.node_opacity
        });
        this.group.addChild(rect);
    }

    // NOTE: VisualDesigner 原型定義
    // ================================
    VisualDesigner.prototype.constructor = VisualDesigner
    VisualDesigner.prototype.getDefaults = function () {
        return VisualDesigner.DEFAULTS
    }
    VisualDesigner.prototype.getOptions = function (options) {
        options = $.extend({}, this.getDefaults(), this.$element.data(), options)
        return options;
    }
    VisualDesigner.prototype.render = function (content) {
        //此處為渲染內容的代碼
    }
    VisualDesigner.prototype.open = function (content) {
        //此處打開操作:清除原來內容,並渲染新內容的代碼
        this.render(content);
    }
    VisualDesigner.prototype.save = function (saveFunc) {
        //此處獲取當前內容,並回調保存代碼,回調的參數包含了當前內容
        saveFunc(this.getContent());
    }
    VisualDesigner.prototype.hasContent = function () {
        return this.getTitle() || this.getContent()
    }
    VisualDesigner.prototype.getContent = function () {
        var $e = this.$element
        var o = this.options

        return $e.attr('data-content')
            || (typeof o.content == 'function' ?
                o.content.call($e[0]) :
                o.content)
    }
    debugger;
    var old = $.fn.visualDesigner
    // VisualDesigner 插件定義,擴展jquery函數
    // =========================
    $.fn.visualDesigner = function (option) {
        debugger;
        return new VisualDesigner(this, option);
    }
    $.fn.visualDesigner.Constructor = VisualDesigner
    // visualDesigner 非沖突
    // ===================
    $.fn.visualDesigner.noConflict = function () {
        $.fn.visualDesigner = old
        return this
    }

}($);


var runMode = { designTime: 1, runTime: 2 };

 

注意上面代碼的幾個知識點

  • +function($){...}($);的寫法和(funtion ($) {}) ($);是一致的,即先定義一個匿名函數,並調用,和var a=function($){}; a($);是等價的。
  • jquery通過$.fn來擴展方法,可以通過$.fn.extend({funcName:function(){}});的形式或者$.fn.funcName=function(){};的方法直接賦值。

一旦定義好了方法jquery組件,我們可以通過以下方法實例化:

    //html:    

     <canvas style="height:300px;width:300px;background-color:gray" id="designView"></canvas>

    //script:
    var view = $("#designView").visualDesigner({ model: runMode.designTime, content: "{\"text\":\"hello world\"}" }); view.open("");

頁面呈現的效果如圖(初始化時畫了一個圓角矩形):

本節js組件就到這里,后續會對javascript的封裝和繼承等再做示例,歡迎繼續關注。

源代碼:visualDesigner1.0.rar

直接運行查看

(本文為原創,在引用代碼和文字時請注明出處)

 
關鍵字
:設計器源代碼,Web設計器,工作流設計器,jQuery插件,組態設計器,SCADA系統設計器,流程圖設計,表單設計建模,報表設計,可視化,設計時,運行時,輕量級開放平台。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM