Javascript:“扩展”没有实例的对象

时间:2013-12-09 21:52:47

标签: javascript jquery kendo-ui

我的情况是我有一个庞大而复杂的对象,我需要在其他地方使用SLIGHT修改(扩展属性等)重新使用它

为了提高简洁性和可重用性,我想我会尝试“扩展”原始对象。所以它看起来像这样......

(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提供模板的实例。的 documentation for 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”的实例。但我已明确告知我不应该在这里使用“新”运算符。我只是想从项目“拉”实际模型,并扩展它。

有没有办法做到这一点?或者这是否超出了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));

1 个答案:

答案 0 :(得分:1)

由于您的对象包含嵌套对象,因此您需要使用深度扩展。为此,请将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/