簡體   English   中英

Javascript:“擴展”沒有實例的對象

[英]Javascript : “extend” an object without an instance

我遇到的情況是我有一個大而復雜的對象,我需要在其他地方稍加修改(擴展屬性等)來重復使用它

為了提高簡單性和可重用性,我認為我會嘗試“擴展”原始對象。 所以看起來像這樣...

(function ($, window) {
    website.module('admin.models', function (exports, require) {
        exports.item = {
                    // large, complex object that will be instantiated by other things
            };
    });
})(jQuery, window);

正在使用的庫是Telerik的Kendo UI ,而我正在使用其MVVM系統。 item函數實際上是kendo.data.Model.define一個實例,該實例正在獲得模板。 Kendo.data.Model.define的文檔

所以這就像...

var item = new website.admin.models.item({
    // specific property values
});

這將創建一個可以綁定到頁面的新視圖模型。 基礎模型具有很多行為,因此更改視圖模型本身不會覆蓋或更改基礎核心。

這很好。 它將所需的功能移到一個單獨的文件中,並清理了較大的實現。 這也是該函數的預期用法,我正在使用的庫的文檔中對此進行了概述。

但是,還有另一個名為schema模型,除了具有一些額外的屬性外,它與item基本上相同。

與其復制並粘貼項目模型,不如嘗試擴展它會更聰明。 所以我嘗試了這種方法

(function ($, window) {
    website.module('admin.models', function (exports, require) {
        exports.schema = $.extend({
               Item: {
                  Id: null, // will be filled in on the UI
                  Name: null, // will be filled in on the UI
                  Description: null, // will be filled in on the UI
                  Timestamp: null // will be filled in on the UI
               },
               Editing: false
        }, website.admin.models.item);
    });
})(jQuery, window);

但是,這不起作用,因為給定的路徑不是“ item”的實例。 但是我被明確告知,我也不應該在這里使用“ new”運算符。 我只是想從項目中“拉”實際模型,然后進行擴展。

有什么辦法嗎? 還是這超出了Javascript的能力?

更新

用於“命名空間”的代碼是這樣;

(function (global) {
    var globalNamespace = global['website'];
    var VERSION = '3.0.1';

    function Module() { }

    function numeric(s) {
        if (!s) {
            return 0;
        }
        var a = s.split('.');
        return 10000 * parseInt(a[0]) + 100 * parseInt(a[1]) + parseInt(a[2]);
    }

    if (globalNamespace) {
        if (numeric(VERSION) <= numeric(globalNamespace['VERSION'])) {
            return;
        }
        Module = globalNamespace.constructor;
    } else {
        global['website'] = globalNamespace = new Module();
    }
    globalNamespace['VERSION'] = VERSION;

    function require(path) {
        path = path.replace(/-/g, '_');
        var parts = path.split('.');
        var ns = globalNamespace;
        for (var i = 0; i < parts.length; i++) {
            if (ns[parts[i]] === undefined) {
                ns[parts[i]] = new Module();
            }
            ns = ns[parts[i]];
        }
        return ns;
    }

    var proto = Module.prototype;

    proto['module'] = function (path, closure) {
        var exports = require(path);
        if (closure) {
            closure(exports, require);
        }
        return exports;
    };

    proto['extend'] = function (exports) {
        for (var sym in exports) {
            if (exports.hasOwnProperty(sym)) {
                this[sym] = exports[sym];
            }
        }
    };
}(this));

由於您的對象包含嵌套對象,因此需要使用深層擴展。 為此,將true作為第一個參數添加到$.extend

exports.schema = $.extend(true, {
   Item: {
      Id: null, // will be filled in on the UI
      Name: null, // will be filled in on the UI
      Description: null, // will be filled in on the UI
      Timestamp: null // will be filled in on the UI
   },
   Editing: false
}, website.admin.models.item);

http://jsfiddle.net/2Jw9L/

當您添加kendoui時,以這種方式擴展它變得很困難(我不會說不可能,可能有一種我沒有想到的方法)來擴展它,並且更容易在模塊外部創建對象並擴展它。

var theObj = {
   ...
};

(function ($, window, kendo) {
    ehrpg.module('admin.models', function (exports, require) {
        exports.item = kendo.data.Model.define($.extend(true,{},theObj));
    });
})(jQuery, window, kendo);

(function ($, window, kendo) {
    ehrpg.module('admin.models', function (exports, require) {
        exports.schema = kendo.data.Model.define($.extend(true,{
            Item: {
                Id: null,
                Name: null,
                Dirty: false,
                Timestamp: null
            }
        },theObj));
    });
})(jQuery, window, kendo);

http://jsfiddle.net/MsrP6/9/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM