1

我正在尝试使用敲除创建一个场景来监视视图模型的更改并通知任何订阅者发生了更改,这工作正常并且通知被触发,但是然后我更改视图并且视图模型更改了通知再次触发,就像在处理视图模型时仍在观察属性一样,有没有办法解决这种行为。

            var options = {
            callback: function () {
                var type = "modelChanged";
                var subscription = $.config.core._subscriptions[type];
                if (subscription) {
                    $.config.core._subscriptions[type] = null;
                }
                self.savePersonalInformation();
            },
            event: "forceSave",
            moduleId: "MemberInformationPersonalInfo"
        };
        $.config.core.subscribeView(options);

注意:订阅视图是一个自定义扩展器,基本上是订阅的包装器。

    monitorPropertyValues: function (model) {
        //subscribe to each property in the model to monitor changes to the value
        // loop through all the properties in the model
        for (var property in model) {
            if (model.hasOwnProperty(property)) {
                if (model[property].subscribe) { //subcribe to observable properties
                    // subscribe to changes
                    model[property].subscribe(function(value) {
                        if (value) {
                            $.config.core.notifySubscribers(true, "modelChanged");
                        }
                    });
                }
            }

        }
    }

初始化视图时调用 MonitorPropertyValues。

我试图实现的基本行为如下,我在页面上有一个选项卡列表,每个选项卡都有自己的视图模型。当我单击一个选项卡时,我想检查视图模型中是否发生了变化。如果有我想向视图模型发送通知以保存所有更改。

4

1 回答 1

2

您可以使用自动触及所有属性的 a 来实现此类功能computed(这是使用 ko.toJS 完成的,它会遍历您的视图模型)。这比您的扩展更简单,并且不应该有任何处置问题。

var viewModel = {
    data: {
        first: ko.observable("Ted"),
        last: ko.observable("Smith") 
    },
    isChanged: ko.observable(false)
}

viewModel.allChanges = ko.computed(function() {
   ko.toJS(viewModel.data);  //just touches all observables, that's it.
});

viewModel.allChanges.subscribe(function() {
    if (!viewModel.isChanged()) {
        viewModel.isChanged(true);     
    }
});

ko.applyBindings(viewModel);​

这个解决方案取自 RP Niemeyer 的小提琴,但我现在找不到原件。无论如何,功劳归于他。

于 2012-07-26T23:09:15.893 回答