【发布时间】:2014-07-22 16:48:56
【问题描述】:
我遇到了未绑定到订阅更新的淘汰模型的问题。我有一个 C# MVC 页面,该页面将模型交付给模板,该模板被解析为 Json,并作为 ko.applyBindings 的 ViewModel 分配的一部分交付原始数据。我订阅了一个 observable,它调用一个方法来更新 viewModel 的数据。不相关的东西被拉出来并重命名,例如用法:
var myViewModel = function (data) {
var self = this;
self.CurrentPage = ko.observable();
self.SomeComplexArray= ko.observableArray([]);
self.Pager().CurrentPage.subscribe(function (newPage) {
self.UpdateMyViewModel(newPage);
});
self.UpdateMyViewModel= function (newPage) {
var postData = { PageNumber: newPage };
$.post('/Article/GetMyModelSearchByPage', postData, function (data) {
ko.mapping.fromJS(data, {}, self);;
});
};
当我执行记录时,我可以看到所有的数据,而且看起来都是正确的。相同的方法用于生成初始模型和更新模型。我在其他页面上使用过这种技术,每次都能完美运行。然而,在这种情况下,我正在寻找它来绑定/更新SomeComplexArray,但这并没有发生。如果我尝试手动执行此操作,则无法在数组上得到正确的绑定,我会得到空白。我想知道是否有什么明显的我做错了,我完全错过了。
编辑:我不知道 ko.mapping 可以被认为是罪魁祸首。标准模型更改也不会影响界面。这是一些在一定意义上不起作用的东西。我有一个可见绑定到数组长度的 p 元素和一个单击绑定到从 SomeComplexArray 中弹出项目的函数的 div 元素。我可以在控制台日志中看到它正在执行其功能(随后的单击导致“未定义”没有该功能)。但是, p 元素永远不会显示。初始数组只有 2 个项目,因此单击即可清空它:
<p data-bind="visible: SomeComplexArray().length === 0">nothing found</p>
<div data-bind="click: function() { UpdateArray(); }">try it manually</div>
-- in js model
self.UpdateArray = function () {
console.log(self.SomeComplexArray());
console.log(self.SomeComplexArray().pop());
console.log(self.SomeComplexArray());
console.log(self.SomeComplexArray().pop());
console.log(self.SomeComplexArray());
});
编辑 2: 来自 @Matt Burland 的评论,我修改了 pop 的调用方式,现在手动方法可以动态修改元素。但是, ko.mapping 仍然没有按我的预期运行。在测试中,我在调用 ko.mapping 之前和之后做了一个特定行的 console.log。没有对 observableArray 进行任何更改。
【问题讨论】:
-
数据是什么样的?它是一个 JavaScript 对象吗?
-
@m.casey:这是一个 JSON 格式的 POCO。在其上使用
JSON.parse()可提供格式正确且可访问的对象。 -
我问的原因,ko.mapping.fromJS() 期望 'data' 应该是一个 JavaScript 对象,所以如果我们传递 'data' 而 'data' 仍然是一个 JSON 对象时间,它不会起作用的,对吧?此外,不确定这是否只是复制/粘贴问题,但映射语句末尾存在语法错误,并且 $.post 函数后缺少“}”。
-
@m.casey:从控制器返回的对象与在页面加载时加载的对象相同(除了其中的数据)。如果该对象无论如何都是格式错误的,它会在 console.log 中给我一个错误(当我尝试各种想法让它工作时,它发生了几次)。
-
将
self.SomeComplexArray().pop()替换为self.SomeComplexArray.pop(),您的编辑将生效。当您执行self.SomeComplexArray()时,您将返回 not 可观察的常规 JS 数组。如果你想让 KO 看到你的数组的变化,你必须使用 observable 数组本身和它的函数。见:jsfiddle.net/AdGe3