仅在事件上更新observableArray

时间:2013-07-17 08:58:50

标签: knockout.js

Example 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

以下是我的想法我应该这样做(但我不完全确定我是否正确)。

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

self.items.replace(oldItem, newItem);

虽然上述看似合乎逻辑,但我不确定它是否充分利用了KnockoutJS。令我烦恼的主要问题是,必须拥有itemViewModel的不可观察版本,我是否可以取消订阅或处理跟踪?

1 个答案:

答案 0 :(得分:1)

Solution jsFiddle


非常感谢 nemesv 提供的文章,它给了我所有我需要完成的工作!对于其他任何以同样的问题磕磕绊绊的人,这就是我所做的。

我使用this article中定义的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();
    };
};

然后将相同的两个commitrollback方法应用于我的整体视图模型(只需在点击时调用$parent.commit$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 获取信息!