Knockout ViewModel 在 ajax 之后被更新,但我的 foreach 没有被触发

Posted

技术标签:

【中文标题】Knockout ViewModel 在 ajax 之后被更新,但我的 foreach 没有被触发【英文标题】:Knockout ViewModel is being updated after ajax, but my foreach is not getting trigged 【发布时间】:2014-11-04 05:55:14 【问题描述】:

我有一个视图模型。从 ajax 调用中检索人员

 var vm = ko.mapping.fromJS(persons, );
 vm.Hobbies = ko.observableArray();
 // other vm objects

viewModel 加载后显示页面,现在我想将另一部分(爱好)加载到视图模型(工作)

// ...ajax call...
 success: function(results)
                ko.utils.arrayForEach(results.hobbies, function(item) 
                    vm.Hobbies.push(item);
                    );
      debugger  
    

// ...end ajax call...

在调试器上,我可以看到我的爱好现在已填充。

我有一个在页面加载时加载的视图

<!--ko if: $data.Hobbies-->
    <div>
      <ul class="fares-by-date-carousel" data-bind="foreach: Hobbies()">
            <li>2</li>
      </ul>
    </div>
<!-- /ko -->

在开始时这部分没有加载(因为尚未调用昂贵的 ajax 调用,这很好) 但是在填充了 vm.Hobbies 之后,上面的 html 部分仍然永远不会显示。

不知道我错过了什么

【问题讨论】:

你能不能把$data.Hobbies改成$root.Hobbies ...谢谢!成功了,我的范围错了 没问题,快速修复总是好的 已为未来的访问者发布了更完整的评论版本。 【参考方案1】:

问题在于您的使用情况:

<!--ko if: $data.Hobbies-->

当您将范围限定到正在迭代的父上下文时,应该使用此选项。例如,您可能会这样:

<!--ko foreach: Person -->
    <!--ko if: $data.Hobbies-->

在本例中,$data 代表每个 Person,因此下面的 if 检查将评估每个 Person 是否有爱好。

如果您不使用此结构(没有父上下文),则不需要使用$data 进行范围,您可以使用$root 作为视图模型范围(即使在嵌套时也可以使用)或离开它一起关闭。两者都应该工作:

<!--ko if: $root.Hobbies-->

<!--ko if: Hobbies-->

Knockout Binding Context

$parent - 这是父上下文中的视图模型对象,即 立即在当前上下文之外。在根上下文中,这是 未定义。

$root - 这是根上下文中的主视图模型对象,即 最顶层的父上下文。它通常是传递给的对象 ko.applyBindings。相当于 $parents[$parents.length - 1]。

$data - 这是当前上下文中的视图模型对象。在里面 根上下文,$data 和 $root 是等价的。在嵌套绑定内部 上下文,此参数将设置为当前数据项(例如, 在 with: person 绑定中,$data 将被设置为 person)。 $数据是 当您想引用视图模型本身而不是 视图模型上的属性。

【讨论】:

以上是关于Knockout ViewModel 在 ajax 之后被更新,但我的 foreach 没有被触发的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Knockout.js 将多个 View 绑定到单个 ViewModel

Knockout.js:页面或页面的一部分上的多个 ViewModel 绑定

仅从 Knockout ViewModel 复制可写项目

刷新页面后可以用 Knockout JS 保存 ViewModel 的数据吗?

将 MVC 模型转换为 Knockout JS ViewModel

从javascript函数更新Knockout viewmodel表单输入绑定