【问题标题】:Knockout template not rendering淘汰赛模板未呈现
【发布时间】:2013-12-12 08:57:55
【问题描述】:

我有一个 viewModel,它包含一个可观察的 folder 对象(初始化时未定义)

我有一个 foreach 模板,它应该显示文件夹的文件,但它不起作用。

jsfiddle

HTML

<div data-bind="template: { if: currentFolder(), foreach: currentFolder.files }">
    <div style="padding: 10px; border: 1px solid #000; background-color: #f0f0f0">
        <span data-bind="text: $data"></span>
    </div>
</div>

<button type="button" id="button">Set current folder</button>

Javascript

var viewModel = {
    currentFolder: ko.observable()
};
ko.applyBindings(viewModel);

document.getElementById('button').onclick = addCurrentFolder;

function addCurrentFolder() {
    var folder = {
        files: [ "File 1", "File 2", "File 3" ]
    };
    viewModel.currentFolder(folder);

    // does nothing

    console.log(viewModel.currentFolder());
};

【问题讨论】:

  • 尝试在 foreach foreach: currentFolder().files 中执行你的 currentFolder observable
  • 是的,这行得通。但是,我需要用一个空对象初始化 currentFolder,否则我会得到一个错误:currentFolder: ko.observable({})。添加您的评论作为答案以标记它

标签: javascript jquery knockout.js knockout-2.0


【解决方案1】:

您的foreach 绑定必须是foreach: currentFolder().files,因为currentFolder 是一个包含对象的可观察对象,因此需要调用它才能“解包”其内容。

【讨论】:

    【解决方案2】:

    尝试在 foreach 中执行你的 currentFolder observable

    foreach: currentFolder().files
    

    【讨论】:

      【解决方案3】:

      您必须使用 observable 或 observableArray 进行数据绑定。我为你制作了小提琴。

      而你的html代码应该如下,

      <div data-bind="foreach: currentFolder">
          <div style="padding: 10px; border: 1px solid #000; background-color: #f0f0f0">
              <span data-bind="text: $data"></span>
          </div>
      </div>
      

      由于我将“currentFolder”与“foreach”绑定,因此淘汰赛期望 currentFolder 作为 observableArray。所以你必须改变视图模型如下,

      var viewModel = {
          currentFolder: ko.observableArray()
      };
      

      然后将值按如下方式推送到可观察数组中,

      viewModel.currentFolder.pushAll([ "File 1", "File 2", "File 3" ])
      

      小提琴: http://jsfiddle.net/hV89w/12/

      编辑:

      您必须将“currentFolder”更改为 observableArray。现在, currentFolder().files 可以呈现你想要的。但是,不建议这样做。因为,它不会捕获文件级别的更改。我的意思是,在执行currentFolder().files.push("File N") 时,用户界面不会更新。

      如果你想更新 UI,那么你必须这样做,

      var folder = currentFolder();
      folder.files.push("File N");
      viewModel.currentFolder(folder);
      

      这种方法是让所有 UI 刷新。我的意思是,这将在以下 HTML 中刷新整个 UI。这个过程被认为成本更高。

      <div data-bind="foreach: currentFolder">
          <div style="padding: 10px; border: 1px solid #000; background-color: #f0f0f0">
              <span data-bind="text: $data"></span>
          </div>
      </div>
      

      【讨论】:

      • 文件夹里面会有其他数组,我不能把它做成可观察数组
      • @RaraituL,我已经解释了当前方法的一些缺点。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-02
      • 2016-02-27
      • 2018-09-05
      • 2011-08-11
      • 2014-06-19
      • 2016-10-08
      • 2012-07-16
      相关资源
      最近更新 更多