【问题标题】:How to add extender to existing observable in Knockout如何在 Knockout 中将扩展器添加到现有的 observable
【发布时间】:2014-06-29 07:00:09
【问题描述】:

我看过这个: http://knockoutjs.com/documentation/extenders.html

问题是我使用 fromJs 来创建我的视图模型,所以我的可观察者已经存在。我认为我可以执行以下操作来添加扩展器:

var data = result.Data;
if (!window.vmRealTimeActivity) {
    window.vmRealTimeActivity = ko.mapping.fromJS(data, mappingKeys);
    ko.applyBindings(vmRealTimeActivity, $('#second-btm')[0]);
} else {
    ko.mapping.fromJS(data, vmRealTimeActivity);
}

vmRealTimeActivity.MyExistingObservable.extend({ numeric: null });
vmRealTimeActivity.MyExistingObservable(9999);  // doesn't call numeric extender

我的扩展器在第一次附加扩展器时被调用,但在尝试更改值之后不会。

我阅读了另一篇 SO 帖子,其中指出 .extend() 创建了一个新的可观察对象,因此您必须这样做,但这也不起作用:

vmRealTimeActivity.MyExistingObservable = vmRealTimeActivity.MyExistingObservable.extend({ numeric: null });

除了没有第二次调用我的格式化程序之外,该值开始返回 NaN。

如何以正确的方式将扩展器附加到现有的 observable?

【问题讨论】:

    标签: javascript knockout.js


    【解决方案1】:

    由于您使用的是映射插件,您可以指定一个create 回调。如果您将以下内容添加到现有的 mappingKeys 中,它可能会起作用(我不知道您的确切映射,因此您可能需要在这里和那里更改位):

    'MyExistingObservable': {
        create: function(options) {
            return new ko.observable(options.data).extend({ numeric: null });
        }
    }
    

    这会在从你的数据映射时产生一个扩展的 observable。

    Here's a jsFiddle 与一个工作示例 (vm1) 和您当前的非工作示例 (vm2) 进行比较

    【讨论】:

    • 谢谢!这将如何应用于可观察数组?以前我这样做: $.each(vmRealTimeActivity.Goals(), function (i, e) { e.Count.extend({ numeric: null }); }); >> 所以我可以扩展自动生成的目标集合的计数属性。我试过这样的东西: create: function (options) { var newArray = ko.observableArray(options.data); >> 基于您的代码,但没有运气。
    • Just to illustrate how you could this with an observable array。那里有很多改进的空间,但我只是想举一个简单的例子。您也可以返回一个新的视图模型,而不是在“创建”回调中返回新的 observables。只需查看映射插件的documentation,该部分名为使用“create”自定义对象构造
    • 谢谢,我去看看。具有讽刺意味的是,因为我之前手动创建了视图模型,然后我切换到使用 fromJs,这似乎比它的价值更多。大声笑
    • 上次给您添麻烦了。我意识到我只需要定义视图模型并使用 JS 来刷新它。但是,我认为无法应用扩展,因为它位于子视图模型中,而 fromJs 对此一无所知。我认为在使用 fromJs 时必须有某种方法来映射子视图模型?我做了一个例子,你可以看到:jsfiddle.net/KrP9D/3
    • Nm,我在这里找到了答案:stackoverflow.com/questions/9951521/…
    【解决方案2】:

    上面的答案是正确的,但是对于任何感兴趣的人,我发现更简单的方法是创建您的视图模型客户端并使用 fromJs 来刷新它们,而不是同时创建和刷新它们。然后,您可以在此处应用答案以支持向父视图模型和子视图模型添加扩展:Map JSON data to Knockout observableArray with specific view model type

    无论采用哪种方法,您都必须创建额外的映射。

    【讨论】:

      猜你喜欢
      • 2013-11-10
      • 2013-06-11
      • 1970-01-01
      • 2019-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多