0

我正在玩 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 是未定义的。我不知道为什么?

但是,如果我在下一条语句中创建可观察到的计算模型,则会定义myViewModel变量。这是为什么?

编辑:其中一个答案表明我在创建对象之前正在访问它。那么这个代码片段是如何工作的呢?

var myViewModel = 
    {
      myFnk : function()
      {
        console.log(myViewModel);
      }
    };

myViewModel.myFnk();

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

4

2 回答 2

1

当你写

alert("This is " + myViewModel);

myViewModel还没有被定义——你还在定义它的过程中!你到底想做什么?您希望能够从内部访问视图模型的最初原因是什么?如果你告诉我们这一点,我很确定我们可以找到一种更惯用的方式来做你需要做的事情。


编辑(在 OP 的编辑之后)

为了能够从视图模型的其他部分引用视图模型的部分,请使用self模式(如Knockout 文档中所推荐的那样):

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("")
}
于 2013-02-27T16:23:54.147 回答
1

这是不时让我绊倒的事情。ko.computed 在定义后立即执行一次。它这样做是为了知道它需要订阅哪些变量来监视更改。

所以在这段代码中

models: ko.computed(function() {
    if (!myViewModel.selectedMake())
        return;

    // TODO: filter models by selected make
})

myViewModel 在它被分配到var myViewModel =行中之前被访问,因为 ko.computed 在它被定义后立即执行该函数。

在您的第二个示例中,您在定义 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
});
于 2013-03-03T01:46:37.113 回答