Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
196 views
in Technique[技术] by (71.8m points)

knockout.js - Knockout same form for edit and create items of an observable array

Newbie to ko, I am struggling with this. I have a form for adding a new address (for simplifying it let's use just one property), that updates an arrray (and displays it in a list), what I would like to achieve is be able to select one of the addresses in the array and be able to display it in the form, This works, but the changes there are not updating the displayed in the list.

Code inside the view:

<div data-bind="with: newAddress" class="span6">
    <input data-bind="value: Line1()" placeholder="Address line 1" />
    <div>
        <button data-bind="click: $parent.addAddress">Add</button>
    </div>
</div>

<div class="span4">
    <div data-bind="visible: addresses().length > 0">
        <div data-bind="foreach: addresses">
            <address>
                <span data-bind="click: $parent.removeAddress">Remove</span>
                <span data-bind="click: $parent.editAddress">Edit</span>
                <div data-bind="text: Line1"></div>                 
            </address>
        </div>
    </div>
</div>

Related code in the script

function ViewModel() {
    var self = this;

    self.addresses = ko.observableArray(ko.utils.arrayMap(addresses, function(address) {
        return new Address(address);
    }));

    self.newAddress = {
        Line1: ko.observable(""),
    };

    self.addAddress = function() {
        self.addresses.push(new Address(this);
        self.newAddress.Line1("");
    };

    self.addAddress = function() {
        self.addresses.push(new Address(this);
        self.newAddress.Line1("");
    };

    self.editAddress = function() {
        self.newAddress.Line1(this.Line1);
    };

    self.remove = function() {
        self.parties.remove(this);
    };

};

// As it is used for both the addresses coming from the server and the added in
// the form I do this check
function Address(address) {
    this.Line1 = ko.isObservable(address.Line1) ? address.Line1() : address.Line1;
}

How could I achieve to bind the changes in the form when one of the addresses selected to the data displayed in the list?

Thanks

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The address is not being updated because it's not an observable.

Change this:

function Address(address) {
    this.Line1 = ko.isObservable(address.Line1) ? address.Line1() : address.Line1;
}

to this:

function Address(address) {
    this.Line1 = ko.observable(ko.isObservable(address.Line1) ? address.Line1() : address.Line1);
}

Also, in cases where you don't know if you have been given an observable or not you can use ko.utils.unwrapObservable to get the value, like this:

this.Line1 = ko.observable( ko.utils.unwrapObservable(address.Line1) );

After reviewing your code more closely I think there are a couple of improvements that can be made:

// Changed newAddress to observable with empty AdressModel
self.newAddress = ko.observable(new Address(""));

// I am assuming correct context when calling this method,
// for example clicking on a list of addressItems in the view
self.editAddress = function(addressItem) {
    self.newAddress(addressItem);
};

// The only thing the update method does is
// emptying the editor form
self.updateAddress = function () {
    self.newAddress(new Address(""));
};

// This method can only be used for adding new items,
// not updating existing items
self.addAddress = function() {
    self.addresses.push(new Address(this));
    self.newAddress(new Address(""));
};

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...