0

我有一堆处理游戏业务逻辑的 JavaScript 类。这些类不依赖于特定的框架,并且应该保持不变。它们代表玩家、他们的属性和可能的​​行动。我现在想使用 KnockoutJS 来创建一个全新的视图,该视图数据量很大,并且具有此游戏中角色类的多个实例。问题是我的 KnockoutJS 驱动的视图模型和游戏类之间的交互,因为后者没有得到更新。

这是 CoffeeScript 中游戏类的摘录:

class AnimaCharacter 
    constructor: (options) ->
        {
            @name,
            @level,
            @characteristics,
            @lifePoints
        } = options

        # ...

        if not @lifePoints
            @lifePoints = this.baseLifePoints()


    baseLifePoints: ->
        20 + @characteristics.constitution * 10

如您所见,有一些基本特征会影响其他值。例如,在这段摘录中,characteristics.constitution值会影响 的结果baseLifePoints()。在幕后还有其他更复杂的计算,例如在战斗中。

现在,我的简单视图由 KnockoutJS 模板组成:

<script id="card-template" type="text/html">
  <div class="charactercard">
    <div class="character-name">
      <h1>
        <span data-bind="text: name"></span><input type="text" data-bind="value: name" />
        <a href="#"><span class="ui-icon ui-icon-pencil character-action"></span></a>
        <a href="#"><span class="ui-icon ui-icon-copy character-action"></span></a>
      </h1>
    </div>
    <dl>
      <dt>Life Points</dt>
      <dd><span data-bind="text: baseLifePoints"></span></dd>
  </div>
</script>

但是,我不知道如何以允许我更新角色类实例的方式设置视图模型。我可以想出一个像这样的简单模型:

class CharacterModel
    constructor: (character) ->
        @character = ko.observable(character)
        @name = ko.observable(character.name)
        @baseLifePoints = ko.observable(character.baseLifePoints())

但这并不会更新实际character.name,或者影响baseLifePoints()我何时更新character.characteristics.constitution

更新角色实例而不将其完全转换为 KnockoutJS 视图的最佳方法是什么?我是否需要以自定义方式订阅更改事件,也许?有没有办法透明地创建对字符类实例的选定属性的“引用”?(我不是 JavaScript 人,所以我在这里从 C++ 中借用了“引用”这个术语。)

ko.mapping.fromJS()不是一个选项,因为它将characteristics.constitution属性的类型更改为自定义的 KnockoutJS 函数,这意味着我不能像在整个课程中那样调用它。

4

1 回答 1

1

您必须订阅 Knockoutside 上的更改并手动更新成员。你可以这样做

KnockoutViewModel = function() {
   //Knockout members goes here

   ko.computed(function() {
      var subscriber = ko.toJSON(this); //Just for sub

      for(var index in this) {
         if(myOtherModel[index] !== undefined) {
            myOtherModel[index] = ko.unwrap(this[index]);
         }
      }
   }, this);
};

http://jsfiddle.net/LMy4r/1/

于 2013-08-30T07:36:23.193 回答