我有一个javascript viewModel,它是使用包含项目列表的“model”数据集启动的。由于我想从我的页面切换项目,我收集订阅中的所有其他数据。 “selectedProject”定义<select>
中的选定值。
我通过将selectedProject启动到Projects-array中的第一个元素来首次触发订阅。
不知何故,我收到错误消息
TypeError: batch is undefined
return item.parentID === batch.parentID;
^
我无法理解为什么。
这是我的代码:
ViewModel = function (model) {
var self = this;
self.selectedProject = ko.observable();
self.selectedText = ko.observable();
self.Textbatches = ko.observableArray();
self.Projects = ko.observableArray(
ko.utils.arrayMap(model, function (item) {
return new Project(item);
}));
self.selectedProject.subscribe(function (project) {
/* ...some code... */
$.getJSON("myService/GetTextbatchesFromDB", "projectID=" + project.projectID,
function (allData) {
var mappedTextbatches = $.map(allData, function (item) {
return new Textbatch(item);
});
self.Textbatches(mappedTextbatches);
self.selectedText(self.Textbatches()[0]);
}
); // End of $.getJSON
/* ...some more code... */
}
self.selectedProject(self.Projects()[0]);
self.parentIDFilteredTextbatches = ko.computed(function () {
var batch = self.selectedText();
return ko.utils.arrayFilter(self.Textbatches(), function (item) {
return item.parentID === batch.parentID; /* ERROR ON THIS LINE */
});
});
}
并且在&lt; HTML&GT;:
<script>
// some code getting "model from the db...
var viewModel = new ViewModel(model);
ko.applyBindings(viewModel);
</script>
我发现如果我在self.selectedText()初始化后移动self.selectedProject.subscribe-function中的“self.parentIDFilteredTextbatches = ko.computed()” - functon,它将在页面第一次时起作用加载。
但是,我不喜欢这样的视图模型结构(也许我会习惯它),更糟糕的是,我在选择新项目时遇到了同样的错误(即,触发了selectedProject.subscription)。 / p>
答案 0 :(得分:2)
你的问题与&#34; mappedTextbatches&#34;的范围有关。变量。可能还有轻微的语法错误。
由于后者的范围,视图模型的Textbatches
属性无法访问mappedTextbatches
变量。稍后当您尝试访问parentID
的{{1}}属性(作为Textbatches[0]
属性中的局部变量集)时,您会收到未定义的错误,因为selectedText
实际上从未实际集。
有关进一步说明和示例,请参阅此jsFiddle:http://jsfiddle.net/0p5fftcc/
Textbatches
我无法对此进行测试以确保,但我猜测如果您将代码更改为以下内容,则不应再收到错误。
/* Demonstrates a similar behavior to
* your current view model.
*/
var currentViewModel = function () {
var self = this;
self.personName = ko.observable('Bob');
self.personAge = ko.observable(10);
self.hasPersonNameChanged = ko.observable(false);
self.personName.subscribe(function (newValue) {
self.hasPersonNameChanged(true);
(function fakeGetJSON() {
/* The local age variable is within the
* function closure, so personAge cannot
* get access to it.
*/
var localAge = 20;
})();
self.personAge(localAge);
});
};
修改以反映帖子中的新代码
在评估之前,请检查var mappedTextbatches = $.getJSON("myService/GetTextbatchesFromDB", "projectID=" + project.projectID, function (allData) {
return $.map(allData, function (item) {
return new Textbatch(item);
});
});
是否有值。见下文。
selectedText
虽然我无法确定所提供信息的方式,但我认为 self.parentIDFilteredTextbatches = ko.computed(function () {
if (self.selectedText() !== undefined) {
var batch = self.selectedText();
return ko.utils.arrayFilter(self.Textbatches(), function (item) {
return item.parentID === batch.parentID; /* ERROR ON THIS LINE */
});
}
return;
});
可以与客户进行互动。假设这一点但又不知道更多,对您的问题的一个不太理想的,虽然快速的解决方法是将self.selectedText
属性声明更改为视图模型顶部的以下内容。这会降低对计算函数的通知速度,该函数保留对Textbatches
和Textbatches
的订阅,希望能够为selectedText
设置足够的时间。
selectedText
这也将绕过您稍后会遇到的问题,即如果您刚刚实施了以后的客户端更新,则新self.Textbatches = ko.observableArray().extend({ rateLimit: 500 });
和旧Textbatches
之间存在不匹配检查selectedText
。
全面的解决方案可能涉及重新设计每个对象所包含的数据结构,但我无法从您的帖子中准确地告诉每个属性应该代表什么。
答案 1 :(得分:0)
$.getJSON("myService/GetTextbatchesFromDB", "projectID=" + project.projectID,
function (allData) {
var mappedTextbatches = $.map(allData, function (item) {
return new Textbatch(item);
});
self.Textbatches(mappedTextbatches);
应该是这个
var mappedTextbatches;
$.getJSON("myService/GetTextbatchesFromDB", "projectID=" + project.projectID,
function (allData) {
mappedTextbatches = $.map(allData, function (item) {
return new Textbatch(item);
});
self.Textbatches(mappedTextbatches);
答案 2 :(得分:0)
&#34;范围&#34;问题是一个两部分问题,不是一个实际问题。
$.getJSON
的一些闭包括号。 $.map
关闭时的定位看起来像$.getJSON
,并直观地显示了实际上并不存在的范围问题。问题是selectedText
与TextBatches
无关,并且由于订阅尚未( synchronicity )填充{{},因此手动设置为undefined
1}}。一旦订阅强制对计算的TextBatches
进行评估仍然具有selectedText
,现在undefined
具有实际数据,然后导致TextBatches
回调执行。
this example中的控制台语句说明了代码中的事件序列。
另一个example fiddle。