我正在玩Knockout JS,在这个代码示例中:
var data =
{
allMakes: ko.observableArray([
{ name: "Toyota" },
{ name: "Fiat"}
]),
allModels: ko.observableArray([
{ name: "Corolla", make: "Toyota" },
{ name: "Celica", make: "Toyota" },
{ name: "Avensis", make: "Toyota" },
{ name: "Uno", make: "Fiat" },
{ name: "Bravo", make: "Fiat" }
])
};
var myViewModel =
{
makes : data.allMakes,
models: ko.computed(function() {
if (!myViewModel.selectedMake())
return;
// TODO: filter models by selected make
}),
selectedModel: ko.observable(""),
selectedMake: ko.observable("")
};
/* Uncomment it to work
myViewModel.models = ko.computed(function() {
if (!myViewModel.selectedMake())
return;
// TODO: filter models by selected make
});
*/
ko.applyBindings(myViewModel);
http://jsbin.com/upaxum/8/edit
我们可以看到我尝试在模型中访问 myViewModel 变量:ko.computed。但是,当此计算的observable运行时,myViewModel未定义。我不知道为什么?
但是,如果我在下一个语句中创建模型计算的observable,则会定义 myViewModel 变量。那是为什么?
编辑:其中一个答案表明我在创建对象之前正在访问该对象。那么为什么这段代码片段会起作用呢?
var myViewModel =
{
myFnk : function()
{
console.log(myViewModel);
}
};
myViewModel.myFnk();
答案 0 :(得分:1)
写作时
alert("This is " + myViewModel);
myViewModel
尚未定义 - 您仍在定义它!你究竟想做什么?您希望能够从内部访问视图模型的原因是什么?如果你告诉我们这一点,我很确定我们可以找到一种更为惯用的方法来做你需要做的事情。
为了能够从视图模型的其他部分引用视图模型的某些部分,请使用self
模式(作为recommended in the Knockout documentation):
function myViewModel() {
var self = this;
self.makes = data.allMakes;
self.models = ko.computed(function() {
if (!self.selectedMake())
return;
// TODO: do something with self.selectedMake()
});
self.selectedModel = ko.observable("");
self.selectedMake = ko.observable("")
}
答案 1 :(得分:1)
这是让我不时绊倒的事情。 ko.computed一旦定义就执行一次。它这样做是为了让它知道需要订阅哪些变量来监视变化。
所以在这段代码中
models: ko.computed(function() {
if (!myViewModel.selectedMake())
return;
// TODO: filter models by selected make
})
myViewModel在被分配到var myViewModel =
行之前被访问,因为ko.computed一旦定义就执行该函数。
在你的第二个例子中,你正在执行函数 AFTER myViewModel已被定义,这就是它工作的原因。如果您想在第一个示例中复制此内容,可以执行以下操作:
var myViewModel =
{
makes : data.allMakes,
selectedModel: ko.observable(""),
selectedMake: ko.observable("")
};
myViewModel.models = ko.computed(function() {
if (!myViewModel.selectedMake())
return;
// TODO: filter models by selected make
});