2

示例 jsFiddle


注意:我目前正在学习 KnockoutJS,因此任何关于最佳实践的指导,或者关于我是否正确地做事的更正总是值得赞赏的!

我正在做一个测试项目,试图掌握出色的 KnockoutJS,现在我需要考虑推迟更新我的observableArray. 我有一个项目的视图模型(我通过 AJAX 调用检索),以及一个列出它们的表。当我单击一个项目时,会弹出一个包含详细信息的模式,并允许我对其进行编辑。我们暂时称它们为项目,这是定义。

var itemViewModel = function (id, name) {
    this.Id = ko.observable(id);
    this.Name = ko.observable(name);
};

当我单击该项目时,我设置了一个selectedItemId然后循环遍历我的项目以寻找正确的项目,当我找到它时,我将其设置为selectedItem并显示模态。

var targetItem = ko.utils.arrayFirst(self.items(), function (current) {
    return current.Id() === self.selectedItemId();
});
self.selectedItem(targetItem);

到目前为止一切正常,但observableArray无论我在模式中单击关闭还是保存,我都会更新。现在,我知道这是正确的行为,但我的问题是:如何observableArray仅在单击Save时更新我的​​?

这就是我认为我应该这样做的方式(但我不完全确定我是否正确)。

我应该有一个不可观察的版本itemViewModel(仍然像以前一样从items集合中提取,但没有可观察的),然后当我在替换项目的模式上单击保存observableArray时调用一些事件,如下所示:

self.items.replace(oldItem, newItem);

虽然以上看起来确实合乎逻辑,但我不确定它是否充分利用了 KnockoutJS。上面让我恼火的主要事情是,必须拥有不可观察的版本itemViewModel,我可以不只是取消订阅或处理跟踪吗?

4

1 回答 1

1

解决方案 jsFiddle


非常感谢nemesv提供的文章,它给了我做我想做的事所需的一切!对于其他遇到同样问题的人来说,这就是我所做的。

我使用了本文protectedObservable中定义的方法,并按照他提交和回滚更改的示例进行操作。所以我这样定义我的:itemViewModel

var itemViewModel = function (id, name) {
    this.Id = ko.protectedObservable(id);
    this.Name = ko.protectedObservable(name);
    this.commit = function () {
        this.Id.commit();
        this.Name.commit();
    };
    this.rollback = function() {
        this.Id.reset();
        this.Name.reset();
    };
};

然后将相同的两个commitandrollback方法应用于我的整体视图模型(它只是在单击Save$parent.commit时调用and方法,如下所示:$parent.rollback

var viewModel = function (items) {
    var self = this;
    self.items = ko.observableArray(items);
    self.selectedItemId = ko.observable();
    self.selectedItem = ko.observable();
    self.selectItem = function () {
        var targetItem = ko.utils.arrayFirst(self.items(), function (current) {
            return current.Id() === self.selectedItemId();
        });
        self.selectedItem(targetItem);
        $('#edit-item-modal').dialog('open');
    };
    self.commit = function () {
        self.selectedItem().commit();
        $('#edit-item-modal').dialog('close');
    };
    self.rollback = function () {
        self.selectedItem().rollback();
        $('#edit-item-modal').dialog('close');
    };
};

我真的很喜欢这个解决方案,所以再次感谢nemesv提供的信息!

于 2013-07-17T10:19:50.703 回答