0

I'm playing around with Knockout JS, and in this code sample:

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

we can see that I try to access myViewModel variable inside models: ko.computed . However myViewModel is undefined when this computed observable runs. And I don't know why?

However if I create models computed observable in next statement, myViewModel variable is defined. Why is that?

EDIT: one of the answers suggests that I'm accessing the object before it is created. So how come that this code snippet works?

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 は、定義されるとすぐに 1 回実行されます。これは、変更を監視するためにサブスクライブする必要がある変数を認識できるようにするためです。

したがって、このコードでは

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

    // TODO: filter models by selected make
})

myViewModel は、行で割り当てられる前にアクセスさvar myViewModel =れます。これは、ko.computed が定義されるとすぐに関数を実行するためです。

2番目の例では、 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 に答える