【问题标题】:viewModel computed functions on the prototype using knockout.jsviewModel 使用 knockout.js 在原型上计算函数
【发布时间】:2016-06-25 19:49:07
【问题描述】:

我正在使用 knockout.js 库,它有助于数据绑定。因此,我不断收到错误消息,即我的变量未在我们 viewModel 原型上的计算函数中定义。我知道这是因为计算函数正在将“this”的上下文更改为窗口,但我似乎无法弄清楚如何让它变回根(viewModel)。我指的方法是javascript中的“消息”。话虽如此,如何将上下文更改回 viewModel?

这是我的代码:

HTML

p#title.col-xs-12.bg-primary.text-center
  | Tic - Tac - Toe!
div.col-xs-3.bg-info
  div.bg-primary.controls
    span
      button.btn.btn-default(data-bind="click:StartMessage.bind($root)")
        | New Game
      p#message.lead(data-bind="text:Messages.bind($root)()")
table.bg-success(style="table-layout:fixed;")
  tr#row1
    td(data-bind="click:Messages.bind($root)")
    td &nbsp
    td &nbsp
  tr#row2
    td &nbsp 
    td &nbsp
    td &nbsp
  tr#row3
    td &nbsp 
    td &nbsp
    td &nbsp

JAVASCRIPT

var message = (function(){
  function Message(){
   this.main = ko.observable(true);
   this.welcome = "Welcome to Tic-Tac-Toe! This is a 2 player game. Click New Game to play!"
   this.turn = ", its your turn."
   this.win = ", you won!"
   this.draw = "It's a draw..."
  }
  return Message;
})()

var players = (function(){
  function Players(){
    this.player1 = ko.observable(true);
    this.player2 = ko.observable(false);
  }
  return Players;
})()

var aBox = (function(){
  function ABox(){
    this.symbol = ko.observable(" ")
  }

  return ABox;
})()

var viewModel = (function(){
  function ViewModel(){
    this.GameMessage = new message();
    this.thePlayers = new players();
    this.r1c1 = new aBox();
    this.r1c2 = new aBox();
    this.r1c3 = new aBox();
    this.r2c1 = new aBox();
    this.r2c2 = new aBox();
    this.r2c3 = new aBox();
    this.r3c1 = new aBox();
    this.r3c2 = new aBox();
    this.r3c3 = new aBox();

  }

/**************************************** 
 ************* Messages *****************
 ****************************************/ 

  ViewModel.prototype.StartMessage = function(){

     this.GameMessage.main(false)
  }

  ViewModel.prototype.Messages = ko.computed(function(){

    if(this.GameMessage.main()){
      return this.GameMessage.welcome;
    }
    else if(this.thePlayers.player1()){
      this.thePlayers.player1(false);
      this.thePlayers.player2(true);
      return "Player 1"+this.GameMessage.turn;

    }
    else if(this.thePlayers.player2())
      this.thePlayers.player1(true);
      this.thePlayers.player2(false);
      return "Player 2"+this.GameMessage.turn;
  },ViewModel)

  return ViewModel;
})()

ko.applyBindings(new viewModel())

我已经尝试将上下文更改为“viewModel”,如图所示、$root 和“this”。

如果您想知道该方法试图完成什么,当单击 NEW MESSAGE 按钮时,它将触发一条消息显示。然后如果点击<td>,它将在之前的位置显示不同的消息。

【问题讨论】:

  • 谢谢我添加了它,我正在使用 knockout.js 进行数据绑定
  • 原型中有Messages 有什么原因吗?我认为由于此计算将是只读的,因此您应该能够将消息作为对象本身的属性。或者在访问计算的原型上创建一个getMessages
  • 所以我在原型上使用它的原因是因为我不想占用比我需要的更多空间。我还听说这样做是最佳做法。出于这个原因,我不想在对象本身上有任何功能。有办法吗?
  • 我不确定是否将它们添加到原型中,但我会说,如果你打算这样做,并且你想拥有正确的上下文 - 拿ko.computed关闭messages 并将其添加到构造函数中:ko.computed(ViewModel.prototype.messages, this) 类似的东西。
  • 是的,好点,尝试该代码不太有效。看看stackoverflow.com/questions/10289251/…他也是这样做的,除了ko.computed(this.messages, this)

标签: javascript mvvm knockout.js prototype computed-observable


【解决方案1】:

ko.computed 函数包含第二个参数allows to bind the computed function this to whichever object you specify。 (在幕后它只是使用apply

因此,当您在原型中定义计算时,您只需将计算绑定到 this,如下所示:

ViewModel.prototype.Messages = ko.computed(function(){
  // your function code
  }, this);

请记住,当您使用原型时,this 指的是您感兴趣的对象实例。

【讨论】:

    猜你喜欢
    • 2016-10-04
    • 1970-01-01
    • 2012-12-07
    • 1970-01-01
    • 2013-01-18
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多