简体   繁体   中英

binding not working in knockout JS

HTML code.

<ul id="cat-list" data-bind="foreach: catList()">
    <li data-bind="text: name, click: $parent.setCurrentCat"> </li>
</ul>
<div id="cat" data-bind="with: currentCat()">

    <h2 data-bind="text: name" id="cat-name"></h2>

    <div data-bind="text: clickCount" id="cat-count"></div>
    <img src="" data-bind="click: $parent.incrementCount, attr: {src: imgSrc}" id="cat-img" alt="cute cat">
    <h4>NickNames</h4>
    <ul data-bind="foreach: nickNames">
        <li data-bind="text: $data"></li>
    </ul>

</div>
<script src="js/lib/knockout-3.2.0.js"></script>
<script src="js/app.js"></script>

The JS code:

var ViewModel = function() {
     var self = this;

    this.catList = ko.observableArray([]);
    initialCats.forEach(function(catItem) {
        self.catList.push( new Cat(catItem) );
    });

    this.currentCat = ko.observable( this.catList()[0]);

    this.incrementCount = function(){
        self.currentCat().clickCount(self.currentCat().clickCount()+1);
    };
    this.setCurrentCat = function(cat) {

    self.currentCat = ko.observable(cat);
    console.log(self.currentCat);
}

var Cat = function(data) {
    this.clickCount = ko.observable(data.clickCount);
    this.name = ko.observable(data.name);
    this.imgSrc = ko.observable(data.imgSrc);
    this.imgAttribution = ko.observable(data.imgAttribution);
    this.nickNames = ko.observable(data.nickNames);
}

ko.applyBindings(new ViewModel())

The initialCats in ViewModel is an array with all cat information. An example element of catlist is

{
    clickCount: 0,
    name: 'Tabby',
    imgSrc: 'tabby.jpg',
    imgAttribution: 'Aman',
    nickNames: ['Tabtab', 'T-bone', 'Mr. T', 'Tabitha Tab Tabby']
}

Althouch clicking on the li elements change the current cat but the corresponding view is not rendered. And the default cat (the first cat) in only rendered. Did i miss something. ?

It's not working probably because you're overwriting currentCat observable instead of just updating the inner object inside setCurrentCat . So, change self.currentCat = ko.observable(cat) to self.currentCat(cat);

Here's a working snippet:

 var initialCats = [{ clickCount: 0, name: 'Tabby', imgSrc: 'https://s20.postimg.org/owgnoq5c9/cat_1.jpg', imgAttribution: 'Aman', nickNames: ['Tabtab', 'T-bone', 'Mr. T', 'Tabitha Tab Tabby'] }, { clickCount: 0, name: 'Tom', imgSrc: 'https://s20.postimg.org/f9d5f0ccp/cat_2.jpg', imgAttribution: 'Aman', nickNames: ['Tommy', 'Timmy'] }] var ViewModel = function() { var self = this; this.catList = ko.observableArray([]); initialCats.forEach(function(catItem) { self.catList.push(new Cat(catItem)); }); this.currentCat = ko.observable(this.catList()[0]); this.incrementCount = function() { self.currentCat().clickCount(self.currentCat().clickCount() + 1); }; this.setCurrentCat = function(cat) { // change here self.currentCat(cat); } } var Cat = function(data) { this.clickCount = ko.observable(data.clickCount); this.name = ko.observable(data.name); this.imgSrc = ko.observable(data.imgSrc); this.imgAttribution = ko.observable(data.imgAttribution); this.nickNames = ko.observable(data.nickNames); } ko.applyBindings(new ViewModel()) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script> <ul id="cat-list" data-bind="foreach: catList()"> <li data-bind="text: name, click: $parent.setCurrentCat"> </li> </ul> <div id="cat" data-bind="with: currentCat()"> <h2 data-bind="text: name" id="cat-name"></h2> <div data-bind="text: clickCount" id="cat-count"></div> <img src="" data-bind="click: $parent.incrementCount, attr: {src: imgSrc}" id="cat-img" alt="cute cat"> <h4>NickNames</h4> <ul data-bind="foreach: nickNames"> <li data-bind="text: $data"></li> </ul> </div> 

Here's a working fiddle

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