【问题标题】:Knockout.js: call function on the prototype but stay in the context of the foreachKnockout.js:在原型上调用函数但留在 foreach 的上下文中
【发布时间】:2016-03-12 02:20:11
【问题描述】:

我正在尝试创建一个使用 knockout.js 的基本井字游戏。我也使用玉作为预处理器;如果您对此感到困惑,请告诉我,但这应该很简单。

所以我需要在我的 HTML 中的 foreach 数据绑定中的对象上使用一个函数,但我还需要访问 viewModel 中的其他对象。我不太确定该怎么做。如果我将它放在 foreach 中的对象上,我可以访问该函数,但是我无法访问该对象之外的对象。

所以我的问题是:如何从可以访问 viewModel 上所有内容的 foreach 上下文调用函数?

这是我的代码:

HTML

table.bg-success(style="table-layout:fixed;")
  tr#row1(data-bind="foreach:topRow")

    td(data-bind="text:symbol,click:function(){$parent.PlayerTurn.bind($root)();$root.changeSymbol()}")

  tr#row2(data-bind="foreach:middleRow")
    td(data-bind="text:symbol,click:function(){$parent.PlayerTurn.bind($root)();$root.changeSymbol()}") 

  tr#row3(data-bind="foreach:bottomRow")
    td(data-bind="text:symbol,click:function(){$parent.PlayerTurn.bind($root)();$root.changeSymbol()}")

JAVASCRIPT

var aBox = (function(position){
  function ABox(){
    this.symbol = ko.observable("");
    this.position = position
    this.count = 0;

  }

  return ABox;
})()

var viewModel = (function(){
  function ViewModel(){
    this.theMessage = new message();
    this.thePlayers = new players();
    this.topRow = ko.observableArray([
      new aBox("r1c1"),
      new aBox("r1c2"),
      new aBox("r1c3"),     
    ]);
    this.middleRow = ko.observableArray([
      new aBox("r2c1"),
      new aBox("r2c2"),
      new aBox("r2c3"),
    ]);
    this.bottomRow = ko.observableArray([
      new aBox("r3c1"),
      new aBox("r3c2"),
      new aBox("r3c3"),
    ]);     
  }

    ViewModel.prototype.changeSymbol = function(){
      this.count+=1;
      if(this.count%2==0){
      this.symbol("O");
      }else{
        this.symbol("X")
      }
    }    

  return ViewModel;
})()

ko.applyBindings(new viewModel())

【问题讨论】:

  • 点击绑定会将当前上下文($data)传递给它的函数。不要使用this。使用传递的参数。
  • 感谢您的评论。我想我不确定你的意思。我尝试将原型中的“this.symbol”更改为“$data.symbol”。我还尝试在“changeSymbol”等于的匿名函数中放置一个参数,并在函数内部使用该参数,但没有成功。对于像我这样成熟的开发者,你能不能再描述一下?
  • 实际上,我的问题是它在原型上,我将它切换到 viewModel 对象本身并且它起作用了。你知道为什么@RoyJ 吗?

标签: javascript knockout.js foreach this


【解决方案1】:

养成将 all 逻辑放在视图模型/javascript 中而不是视图中的习惯。另外,请通读the click binding handler documentation,它实际上回答了您的大部分问题,而且只是简短的阅读。

基本上是这样的:

td(data-bind="text:symbol, click: $root.changeSymbol") 

那么你就可以在$root上拥有这个功能了:

var self = this;
self.changeSymbol = function(childVm) {
  console.log(self); // is the $root
  console.log(childVm); // the item from the foreach
}

如果您需要访问“子”和“根”之间的元素(即在两者之间存在$parent),您应该:

  • changeSymbol 函数移动到$parent 并确保父视图模型具有对 父视图的引用(如果您需要在函数内部使用它);或
  • 在子 vm 上放置父级的属性,以便函数可以调用 childVm.parent 来访问该视图模型。

作为脚注,如果您绝对必须,您可以这样做:

td(data-bind="text:symbol, click: function() { $root.changeSymbol($root, $parent, $data); }") 

但这可能意味着您有一个 XY 问题,并且您的视图模型没有按照应有的方式构建。

【讨论】:

    猜你喜欢
    • 2016-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多