在创建对象的语句中未定义对象文字变量

时间:2013-02-27 16:21:15

标签: javascript knockout.js object-literal

我正在玩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();

http://jsbin.com/eyutip/1/edit

2 个答案:

答案 0 :(得分:1)

写作时

alert("This is " + myViewModel);

myViewModel尚未定义 - 您仍在定义它!你究竟想做什么?您希望能够从内部访问视图模型的原因是什么?如果你告诉我们这一点,我很确定我们可以找到一种更为惯用的方法来做你需要做的事情。


编辑(OP编辑后)

为了能够从视图模型的其他部分引用视图模型的某些部分,请使用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
});