CanJS对象列表自动进行子类化和重类化

CanJS object list automatic subclassing and reclassing

本文关键字:子类 对象 列表 CanJS      更新时间:2023-09-26

远程第三方JSONP服务器为我的CanJS脚本提供了一个结果列表,如下所示:

[
    { "class": "ABaseClass", "value": "1"},
    { "class": "ASubClass", "value": "2"},
    { "class": "ABaseClass", "value": "3"},
    { "class": "ASubClass", "value": "4"}, 
    ...
]

其中type是预期的对象类,在CanJS中使用can.Model.extend:定义

以下简化代码演示了CanJS设置:

ABaseClass = can.Model.extend({ ... }, {
    'findAll': { 'url': 'the url', 'dataType': "jsonp" }
    // this is modified source code and may not run
});
// ASubClass is a subclass of ABaseClass.
ASubClass = ABaseClass.extend({ ... }, { ... });

问题:

当调用ABaseClass.findAll({}, function(data) { ... })(它为更多对象调用JSONP端点)时,回调将获得CanJS模型的列表,但仅为ABaseClass类。

问题:

CanJS是否提供了一种助手方法,可以根据对象列表中的字段自动创建子类?如果没有,我该如何着手实施呢


预期输出:

[
    (new ABaseClass(...)),
    (new ASubClass(...)),
    (new ABaseClass(...)),
    (new ASubClass(...)),
    ...
]

环境:

  • CanJS:1.17
  • jQuery:1.10.1
  • 我无法控制端点返回的对象类型
  • 多个AJAX调用不是可接受的解决方案

实现这一点的最简单方法是重写models方法,并为类找到正确的模型,如下所示:

ABaseClass = can.Model.extend('ABaseClass', {
    'findAll': { url: "/the_url", dataType: "jsonp" },
    models: function(results){
        return_models = new can.List();
        can.each(results, function(result){
            return_models.push( window[result.class].model(result.value) )
        })
        return return_models;
    }
}, {});
ASubClass = ABaseClass.extend('ASubClass', {}, {});
ABaseClass.findAll({}, function(results){
    console.log(results);
})

它的作用是:

  1. findAll返回时,它将其结果发送给models方法
  2. models方法然后在每个结果上循环
  3. 然后它会找到附加到窗口的模型构造函数。(window[result.class]
  4. 然后我们在构造函数上调用model来构造/更新模型实例
  5. 将模型实例添加到can.List并返回

我已经在CanJS 2.0.x中测试过了,它在这里运行良好。

你可以在文档中找到更多关于这一切如何工作的细节:

  • http://canjs.com/docs/can.Model.models.html
  • http://canjs.com/docs/can.Model.model.html

看起来这些将在CanJS 2.1.0中被弃用,取而代之的是.parseModels.parseModel

  • http://www.bitovi.com/blog/2014/02/canjs-infrastructure-improvements.html#perpetual-测试版预发布