KnockoutJS 使用映射插件订阅属性更改 [英] KnockoutJS subscribe to property changes with Mapping Plugin

查看:21
本文介绍了KnockoutJS 使用映射插件订阅属性更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

无论如何我可以告诉淘汰映射插件订阅调用某个函数的所有属性更改吗?

我意识到我可以通过这种方式手动订阅属性更改事件:

var viewModel = {名称:ko.observable('foo'),}//在这里手动订阅viewModel.name.subscribe(function(newValue){//做工作})

不过,我希望能够进行一般订阅,因为我的视图模型可能会有所不同,所以我不想对属性名称进行硬编码.我创建了一个执行此操作的函数,但这可能不是最好的方法.它适用于除 IE7 及以下的所有浏览器.

这里我将一个视图模型作为参数,并尝试对其订阅属性进行反思:

function subscribeToKO(data) {$.each(data, function (property, value) {if (getType(value) == "Object")数据[属性] = subscribeToKO(value);否则如果(getType(值)==数组"){$.each(value, function (index, item) {item = subscribeToKO(item);});}别的 {如果(值.订阅){值.订阅(函数(新值){//做工作});}}});返回数据;}

就像我说的那样有效,但由于我使用的是映射插件,我希望有一个钩子可以用来为它提供一个通常订阅属性更改的函数.

类似于:

映射 = {创建:功能(选项){options.data.subscribe(function(newValue){//做工作 ???});}}ko.mapping.fromJS(viewModel, mapping);

有什么想法吗?

解决方案

这里是一个基于 Ryan Niemeyer 的脏旗.
单击此处查看 JsFiddle.

HTML:

    <li>电话:<输入数据绑定=值:电话"/><li>地址:<输入数据绑定=值:地址"/></ol>

Javascript:

var 模型 = {电话:ko.observable('0294658963'),地址:ko.observable('167 New Crest Rd')};//用于创建已更改标志的淘汰扩展(类似于 Ryan 的脏标志,但每次更改后都会自行重置)ko.changedFlag = 函数(根){var 结果 = function() {};var initialState = ko.observable(ko.toJSON(root));result.isChanged = ko.dependentObservable(function() {var changed = initialState() !== ko.toJSON(root);如果(更改) result.reset();退货变了;});结果.reset = function() {初始状态(ko.toJSON(根));};返回结果;};//将更改的标志属性添加到模型model.changedFlag = new ko.changedFlag(model);//订阅更改model.changedFlag.isChanged.subscribe(function(isChanged) {if (isChanged) alert("模型改变");});ko.applyBindings(模型);

Is there anyway I can tell the knockout mapping plugin to subscribe to all property changes call a certain function?

I realize I can manually subscribe to the property change event in this manner:

var viewModel = {
    name: ko.observable('foo'),
}

// subscribe manually here
viewModel.name.subscribe(function(newValue){
   // do work
})

I would like to be able to generically subscribe though, since my view models may vary, I don't want to hardcode the property names. I created a function that does this, but it may not be the best approach. It works over all browsers except IE7 and below.

Here I take a viewmodel as an argument and try to reflect on it subscribing to the properties:

function subscribeToKO(data) {

        $.each(data, function (property, value) {
            if (getType(value) == "Object")
                data[property] = subscribeToKO(value);
            else if (getType(value) == "Array") {
                $.each(value, function (index, item) {
                    item = subscribeToKO(item);
                });
            }
            else {
                if (value.subscribe) {
                    value.subscribe(function (newValue) {
                        // do work                                         
                    });
                }
            }
        });
        return data;
    }

Like I said this works, but since I am using the mapping pluging I was hoping there was a hook I could use to provide it with a function that will generically subscribe to property changes.

Something like:

mapping = {
   create: function(options){
       options.data.subscribe(function(newValue){
            // do work ???
       });
   }
}

ko.mapping.fromJS(viewModel, mapping);

Any ideas?

解决方案

Here's a generic approach based on Ryan Niemeyer's dirty flag.
Click here for the JsFiddle.

Html:

<ol>
<li>
    Telephone : <input data-bind="value: telephone"/>
</li>
<li>
    Address : <input data-bind="value: address"/>
</li>
</ol>​

Javascript:

var model = {
    telephone: ko.observable('0294658963'),
    address: ko.observable('167 New Crest Rd')

};
// knockout extension for creating a changed flag (similar to Ryan's dirty flag except it resets itself after every change)
ko.changedFlag = function(root) {
    var result = function() {};
    var initialState = ko.observable(ko.toJSON(root));

    result.isChanged = ko.dependentObservable(function() {
        var changed = initialState() !== ko.toJSON(root);
        if (changed) result.reset();
        return changed;
    });

    result.reset = function() {
        initialState(ko.toJSON(root));
    };

    return result;
};
// add changed flag property to the model
model.changedFlag = new ko.changedFlag(model);
// subscribe to changes
model.changedFlag.isChanged.subscribe(function(isChanged) {
    if (isChanged)  alert("model changed");
});
ko.applyBindings(model);​

这篇关于KnockoutJS 使用映射插件订阅属性更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆