为什么在此代码中m“未定义”:
currentViewModel = ko.mapping.fromJS(viewModel);
currentViewModel.getReport = function(reportId) {
for(var i=0;i<currentViewModel.availableReports().length;i++) {
if(currentViewModel.availableReports()[i].id == reportId) {
var m = currentViewModel.availableReports()[i];
return currentViewModel.availableReports()[i];
}
}
}
我将getReport()称为onclick事件,我想将报表对象发送到视图(模态)我可以在availableReports上做一个foreach,它就在那里。当我运行调试器时,它遍历数组并找到正确的数组。但是为什么我不能把它拉出阵列呢? “m”仍未定义,函数返回undefined。
我在这里缺少什么?
编辑:此处有一个跟进问题: Can knockout.js wait to bind until an onClick?
答案 0 :(得分:2)
您只需将if(currentViewModel.availableReports()[i].id ...
更改为if(currentViewModel.availableReports()[i].id() ...
,因为映射id
后会成为可观察的,即函数。
更新的代码:
currentViewModel = ko.mapping.fromJS(viewModel);
currentViewModel.getReport = function(reportId) {
for (var i = 0; i < currentViewModel.availableReports().length; i++) {
if (currentViewModel.availableReports()[i].id() == reportId) {
var m = currentViewModel.availableReports()[i];
return currentViewModel.availableReports()[i];
}
}
}
演示 - Fiddle。
答案 1 :(得分:0)
我会在这里重复@NikolayErmakov's answer中的解决方案,但想要添加两件事来获得更完整的答案。你以:
结尾...
m
仍未定义,函数返回undefined
。我在这里缺少什么?
你错过了两件事:
var m
内第一个语句的if
位是hoisted到当前范围的顶部(函数的顶部)。这就是为什么调试器可以告诉你m
是什么,即使你从未到达它所在的代码行。if
)而没有看到明确的return
语句,it will return undefined
。 为了更好地理解这一点,你应该像这样解释你的功能:
currentViewModel.getReport = function(reportId) {
var m;
for (var i = 0; i < currentViewModel.availableReports().length; i++) {
if (currentViewModel.availableReports()[i].id == reportId) {
m = currentViewModel.availableReports()[i];
return currentViewModel.availableReports()[i];
}
}
return undefined;
}
有些人(e.g. Douglas Crockford)建议将var
语句放在函数的顶部,尽管这在某种程度上是一种风格问题。我不认为很多人在函数结束时显式返回undefined
,但在你的情况下,我可能明确表示该场景并返回null
(或抛出一个甚至出错。
正如所承诺的那样,我将重复实际解决方案,因为我同意另一个答案:
id
作为函数来获取其值(因为mapping
插件将映射到observable()
s。另外:
===
代替==
这是我的v0.5版本:
currentViewModel.getReport = function(reportId) {
var m = null, reports = currentViewModel.availableReports();
for (var i = 0; i < reports.length; i++) {
if (reports[i].id() === reportId) {
m = reports[i];
return m;
}
}
return m;
}
但我会优化它到这个v1.0:
currentViewModel.getReport = function(reportId) {
var reports = currentViewModel.availableReports();
for (var i = 0; i < reports.length; i++) {
if (reports[i].id() === reportId) {
return reports[i];
}
}
return null;
}
为了完整起见,这是另一个在数组上使用filter
的版本:
currentViewModel.getReport = function(reportId) {
var reports = currentViewModel.availableReports().filter(function(r) { return r.id() === reportId; });
return reports.length >= 1 ? reports[0] : null;
}