防止knockout绑定立即更新复杂对象的目标属性

时间:2013-07-06 19:26:49

标签: knockout.js

前几天我问过这个问题,

Knockout same form for edit and create items of an observable array

现在我想稍微改变一下这种行为。

正如你在小提琴中看到的那样http://jsfiddle.net/danne567/gTHpu/31/当你从输入文本中聚焦时,目标就会更新。我想延迟这一点,直到你点击更新按钮。

我已经做了一些解决方法并且似乎有效,但我对此并不满意:

我没有创建地址observable的内部属性,我已经向Address对象添加了一个命令并按它对数组进行了排序。然后,每当您编辑地址并单击更新时,我将其从可观察数组中删除并再次添加(使用更改的字段)并再次对数组进行排序。

self.updateAddress = function() {
    self.AddressEditingMode(false);
    self.addresses.remove(this);
    self.addresses.push(new Address(ko.utils.unwrapObservable(self.formAddress),self.EditingAddressOrder()));
    self.addresses(_.sortBy(self.addresses(), function(address) { return address.Order; }));
    self.emptyAddressForm();
};

我理解很难将我的解释放在上下文中,所以请随意指出我需要的任何内容。

谢谢,

聚苯乙烯。 _.sortBy用于​​下划线功能。

2 个答案:

答案 0 :(得分:1)

我尝试更正您的代码,在jsfiddle上浏览:http://jsfiddle.net/gTHpu/32/

首先,我更改了地址构造函数(添加id参数)

var id = 1;
function Address(address) {
    this.id = id++;
    this.Line1 = ko.observable(ko.utils.unwrapObservable(address.Line1));
}

然后,我解释了新地址var:

self.addresses = ko.observableArray(ko.utils.arrayMap(addresses, function(address) {
    return address.id ? address : new Address(address);
}));
self.newAddress = ko.observable('');
self.addAddress = function() {
    self.addresses.push(new Address({Line1: this.newAddress()}));
    self.newAddress('');
};

然后,添加删除功能

self.removeAddress = function (address) {
    self.addresses.remove(address);
}

我更改了更新地址流程:

self.addressToEdit = null;
self.editAddress = function(addressItem) {
    self.addressToEdit = addressItem;
    self.newAddress(addressItem.Line1());
};

self.updateAddress = function () {
    if (self.addressToEdit) {
        self.addressToEdit.Line1(self.newAddress());
        self.addressToEdit = null;
    }
    self.newAddress('');
};

该解决方案是否适合您?

PS。对不起我的英语,请随时纠正我,因为我是非母语人士:)

答案 1 :(得分:1)

大多数情况下,但您要做的是处理地址的新副本,然后仅在更新时应用更改。我修改了你的地址视图模型,使其更容易处理更新:

地址视图模型:

function Address(address) {
    var self = this;
    self.Line1 = ko.observable();

    // we'll use this method to update existing addresses that have been modified
    self.initialize = function (data) {
        self.Line1(ko.utils.unwrapObservable(data.Line1));
    }

    self.initialize(address);
}

主VM的主要变化:

    // this will store the currently selected address from the observableArray
    var selectedAddress;
    // added this just as example, use it to toggle which buttons to show (see fiddle)
    self.isEditing = ko.observable(false);

    // helper function to clear out the input if the user doesnt want to 
    //  update the address or is finished with it
    function clearSelected() {
        self.isEditing(false);
        self.newAddress(new Address(""));
    }

    self.editAddress = function (addressItem) {
        // set the address item that was picked to selectedAddress variable
        selectedAddress = addressItem;
        // set what mode we're in
        self.isEditing(true);
        // create new copy of address to work off of based on the clicked address item
        self.newAddress(new Address(addressItem));
    };

    // once update is clicked, the copy of the context is passed to this function
    self.updateAddress = function (address) {
        // call the new initialize function on the address 
        //  view model that we've saved as a reference in the 
        //  original list with whatever values have changed
        selectedAddress.initialize(address);
        // clear the selected item and reset the mode so we can add new items
        clearSelected();
    };

小提琴http://jsfiddle.net/58mU5/