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

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

问题描述

反正我可以告诉敲除映射插件订阅所有属性更改以调用某个函数吗?

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
})

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

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.

在这里,我将viewmodel作为参数,并尝试通过订阅属性来反思它:

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.

类似的东西:

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

ko.mapping.fromJS(viewModel, mapping);

有什么想法吗?

推荐答案

以下是基于 JsFiddle .

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:

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使用Mapping Plugin订阅属性更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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