【问题标题】:binding not working in knockout JS绑定在淘汰赛 JS 中不起作用
【发布时间】:2018-05-21 08:10:52
【问题描述】:

HTML 代码。

<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>

JS代码:

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())

ViewModel 中的 initialCats 是一个包含所有猫信息的数组。 catlist 的一个示例元素是

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

虽然点击 li 元素会改变当前的猫,但不会渲染相应的视图。而默认的猫(第一只猫)只在渲染中。我错过了什么。 ?

【问题讨论】:

    标签: javascript knockout.js data-binding


    【解决方案1】:

    它不工作可能因为你覆盖currentCat observable 而不是仅仅更新setCurrentCat 中的内部对象。所以,把self.currentCat = ko.observable(cat)改成self.currentCat(cat);

    这是一个有效的 sn-p:

    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

    【讨论】:

    • 答案有效,虽然我不完全理解它为什么会这样工作..!!
    • @aman 我的理论是在applyBindings() 被调用之后添加的任何新的observable 都不起作用。当你这样做时,self.currentCat = ko.observable(cat); 它将 覆盖 以前的 observable 的依赖项,并且不会绑定新的 observable,除非你再次 cleanNodeapplyBindings
    猜你喜欢
    • 1970-01-01
    • 2014-10-28
    • 1970-01-01
    • 2021-02-14
    • 2013-08-14
    • 2014-01-10
    • 2015-12-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多