2013-08-30 3 views
0

У меня есть куча классов JavaScript, обрабатывающих бизнес-логику игры. Эти классы не привязаны к определенной структуре и остаются таковыми. Они представляют игроков, их атрибуты и возможные действия. Теперь я хотел бы использовать KnockoutJS для совершенно нового представления, которое очень тяжело для данных и имеет несколько экземпляров этого игрового класса. Проблема заключается в взаимодействии моей модели модели KnockoutJS и игрового класса, потому что последняя не обновляется.Knockout.js и пользовательские классы

Это отрывок из класса игры в 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? Может быть, мне нужно подписаться на изменение событий по-своему? Есть ли способ прозрачного создания «ссылок» на selcted-свойства экземпляров класса символов? (Я не парень JavaScript, поэтому я заимствовал термин «ссылка» из C++ здесь.)

ko.mapping.fromJS() это не вариант, так как он изменяет тип characteristics.constitution собственности в пользовательскую функцию KnockoutJS, что означает I не может называть это так, как я делаю всю оставшуюся часть класса.

ответ

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/

+0

Спасибо, что делает трюк. Особенно для цикла (... in ...) приятно легко развернуть то, что важно! – Technaton

+0

Вы также можете использовать hasOwnProperty для более безопасного подхода http://jsfiddle.net/LMy4r/2/ – Anders

Смежные вопросы