简体   繁体   中英

how to attach a selected observable to a newly added item?

I'm new to knockout. I already have this fiddle in which it will:

  1. Populate the left box as the lists of items
  2. Once you select an item in the left box, it will show the detailed item in the right box

It seems that I have it running correctly. But I want to add more to it.

  1. Upon load, select the first foo with its displayed details
  2. Once I click the + Add foo link, it will add new foo and have it highlighted then the editor in the right box will appear then when I click save it will add it to the collection of foo.

Is this possbile?

Snippet below

 var data = [ { id: 1, name: "foo1", is_active: true }, { id: 2, name: "foo2", is_active: true }, { id: 3, name: "foo3", is_active: true }, { id: 4, name: "foo4", is_active: false }, ]; var FooBar = function (selected) { this.id = ko.observable(""); this.name = ko.observable(""); this.is_active = ko.observable(true); this.status_text = ko.computed(function () { return this.is_active() === true ? "Active" : "Inactive"; }, this); this.is_selected = ko.computed(function () { return selected() === this; }, this); }; var vm = (function () { var foo_bars = ko.observableArray([]), selected_foo = ko.observable(), load = function () { for (var i = 0; i < data.length; i++) { foo_bars.push(new FooBar(selected_foo) .name(data[i].name) .is_active(data[i].is_active) .id(data[i].id)); } }, select_foo = function (item) { selected_foo(item); }, add_foo = function () { // I have tried this but ain't working at all. Please help // foo_bars.push(new FooBar(selected_foo)); }; return { foo_bars: foo_bars, load: load, selected_foo: selected_foo, select_foo: select_foo, add_foo: add_foo }; }()); vm.load(); ko.applyBindings(vm); 
 .box { float: left; width: 250px; height: 250px; border: 1px solid #ccc; } .selected { background-color: #ffa !important; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <div class="box"> <a href="#" data-bind="click: add_foo">+ Add foo</a> <table> <thead> <tr> <th>Name</th> <th>Status</th> </tr> </thead> <tbody data-bind="foreach: foo_bars"> <tr data-bind="click: $root.select_foo, css: { selected: is_selected }"> <td><a href="#" data-bind="text: $data.name"></a></td> <td data-bind="text: $data.status_text"></td> </tr> </tbody> </table> </div> <div class="box" data-bind="with: selected_foo"> Id: <span data-bind="text: id"></span><br /> Name: <input type="text" data-bind="value: name" /><br /> Status: <input type="checkbox" data-bind="checked: is_active"> <span data-bind="text: status_text"></span><br /> <button>Save</button> </div> 

The new object you are adding didn't have the name and id assigned, that is probably why it was not showing up. In addition to that, once the new object is added you will need to select it before it can show up as selected in the left panel. below is my code definition for your add method

add_foo = function() {
    var new_foo=new FooBar(selected_foo)
        .name("foo"+(foo_bars().length+1));
    select_foo(new_foo);
    foo_bars.push(new_foo);
};

and the complete working fiddle can be found here http://jsfiddle.net/euq48em4/1/

demo: http://jsfiddle.net/wguhqn86/4/

load = function () {
    for(var i = 0; i < data.length; i++){
        foo_bars.push(new FooBar(selected_foo)
              .name(data[i].name)
              .is_active(data[i].is_active)
              .id(data[i].id)
        );
    }
    selected_foo(foo_bars()[0]); // default select first foo
},


add_foo = function() {
    var count = foo_bars().length + 1;
    var newItem = new FooBar(selected_foo).name('')
                .is_active(true)
                .id(count)
    foo_bars.push(newItem);
    selected_foo(newItem);
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM