【问题标题】:Trouble binding tables to Knockout collection无法将表绑定到 Knockout 集合
【发布时间】:2014-01-24 02:44:09
【问题描述】:

我不明白为什么这些 Knockout 表绑定不起作用:

Javascript:

$(function () {

    var FileObject = function(id, name) {
        this.id = id;
        this.name = name;
    };

    var FilesModel = function() {

        this.filesSelected = ko.observable(false);  
        this.myFiles = ko.observableArray([new FileObject(1, 'test_1')]);
        this.myFiles.push(new FileObject(2, 'test_2'));
    };

    var filesModel = new FilesModel();
    window.filesModel = filesModel;
    ko.applyBindings(filesModel);

    filesModel.myFiles().push(new FileObject(3, 'test_3')); // This never shows

    alert(filesModel.myFiles().length); // Shows 3 items

});

HTML:

<h3>TABLE 1</h3>
<table> 
<tbody data-bind="foreach: myFiles">
    <tr>
        <td>FILE:</td>
        <td data-bind="text: name"></td>
    </tr>    
</tbody>
</table>

<h3>TABLE 2</h3>
<table>
<tbody data-bind="foreach: myFiles()">
    <tr>
        <td>FILE:</td>
        <td data-bind="text: name"></td>
    </tr>    
</tbody>
</table>

在这两个表中,前 2 个文件将显示,但第 3 个文件不显示。我错过了什么?

【问题讨论】:

  • 创建一个 jsFiddle 来演示这个问题,应该是一个你可能忽略的简单语法错误

标签: javascript knockout.js


【解决方案1】:

真的很亲密。需要指出的两个主要事项:

  1. 状态不是可观察的,您正尝试使用 text: status() 解开它。
  2. 您将新的FileObject 推入一个未包装的数组中,这意味着您完全绕过了可观察对象。将新项目直接推送到 observable 数组中,你会有更好的运气。

我根据您的原始来源整理了一个jsbin example

具体来说,这个:

filesModel.myFiles().push(new FileObject(3, 'test_3')); // This never shows

应该是:

filesModel.myFiles.push(new FileObject(3, 'test_3')); // Now it does

【讨论】:

  • 未包装的数组正是问题所在 - 谢谢@Ross!
  • (状态的东西只是我草率的复制/粘贴-与问题无关)
  • BONUS:那么我是data-bind="foreach: myFiles"还是data-bind="foreach: myFiles()"有关系吗?
  • 在我的脑海中 - 在这种情况下,我认为这并不重要。测试我的记忆,foreach 在从更改myFiles 触发更改事件后调用(并在需要时解包)myFiles。不过,我必须四处看看才能确定。
  • @Yarin 如果您想在视图中绑定它之前和之后查看差异 console.log(myFiles())。具体查看 observable 的订阅者,您可以确保已将 DOM 元素注册为订阅者。
【解决方案2】:

在您的 HTML 中,您尝试数据绑定 status(),但 status 不是可观察的。一种方法是让您的 FileObject 成员可观察。 此外,您的第三个 FileObject 从未显示,因为您的语法错误。而不是filesModel.myFiles().push,应该只是filesModel.myFiles.push

updated fiddle

$(function () {
    var FileObject = function(id, name, size, status, progress) {
        this.id = ko.observable(id);
        this.name = ko.observable(name);
        this.status = ko.observable(status);
    };

    var FilesModel = function() {

        this.filesSelected = ko.observable(false);  
        this.myFiles = ko.observableArray([new FileObject(1, 'test_1')]);
        this.myFiles.push(new FileObject(2, 'test_2', 3, 'status'));
    };

    var filesModel = new FilesModel();
    window.filesModel = filesModel;
    ko.applyBindings(filesModel);

    filesModel.myFiles.push(new FileObject(3, 'test_3')); // This never shows

    alert(filesModel.myFiles().length); // Shows 3 items

});

【讨论】:

  • @rwisch45- 谢谢,这是语法问题,Ross 比你少了几分
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多