2013-03-24 80 views
1

产生一个ViewModel我有以下视图模型:添加属性的子对象在淘汰赛映射插件

var ViewModel = function(setData, dummyCard) { 
    var self = this; 
    ko.mapping.fromJS(setData, {}, self); 

    self.cardCount = ko.computed(function() { 
     //debugger; 
     return self.cards().length; 
    }); 

    self.editing = ko.observable(false); 

    self.edit = function() { 
     debugger; 
     self.editing(true); 
    }; 

}; 

该视图模型是用来显示属于一组牌的名单。我想允许用户通过以下编辑这些卡的(双方同时)的侧面:

<!-- ko foreach: cards --> 
     <!-- ko foreach: sides --> 
     <div data-bind="visible: !$root.editing()" class="span5 side-study-box"> 
      <p data-bind="text: content">SIDE 1</p> 
     </div> 
     <!-- /ko --> 
<!-- /ko --> 

我每次添加的例子编辑功能,在这里(看到伯特的hasFocus例子Bertington):http://knockoutjs.com/documentation/hasfocus-binding.html

虽然编辑属性附加到$ root(Set)对象,而不是$ parent(Card)对象,但这并不完美。我认为,为了使这项工作的方式涉及到“创造”的方法在这里看到:Adding properties to the view model created by using the Knockout JS mapping plugin

需要什么语法来使这些属性在一旁的家长吗?

编辑:到目前为止,我有:

var ViewModel = function(setData, dummyCard) { 
    var self = this; 

    var cardModel = function(data) { 
     debugger; 
     ko.mapping.fromJS(data, {}, this); 

     this.editing = ko.observable(false); 

     this.editing = function() { 
      debugger; 
      this.editing(true); 
     }; 
    }; 

    var mapping = { 
     'cards': { 
      create: function(options) { 
       return new cardModel(options.data); 
      } 
     } 
    }; 

self.cardCount = ko.computed(function() { 
     //debugger; 
     return self.cards().length; 
    }); 

这是相当与JS的其余部分,虽然工作没有 - 现在“卡()”是不确定的。现在挖掘它,但如果任何人有任何提示,我都耳朵!

回答

0

尽管您已经在此模型中定义了“cardModel”并调用了KO映射,但在应用KO绑定时,默认情况下,函数体(即模型定义)不会被执行。此外,您的代码将“卡”映射到“cardModel”,因此,“卡”阵列在根模型视图中不可用。这些共同是你看到卡片未被定义的原因。

我还注意到一个问题,“编辑”属性。看起来你有一个可观察的和具有相同名称的“编辑”的函数,这将导致一个无结束的递归。

随着你给出的描述,我假设你正试图映射一个包含卡片元素的JSON数组,并定义了一种获得你想要完成的方法。代码可在this fiddle中找到。

在小提琴的代码下面提到的读者方便

的JavaScript

var cardsJSON = { 
    "cards" : [{ 
     "cardName" : "Card1", 
     "sides" : ["Side1", "Side2"] 
    }, { 
     "cardName" : "Card2", 
     "sides" : ["Side1", "Side2"] 
    }, { 
     "cardName" : "Card3", 
     "sides" : ["Side1", "Side2"] 
    }] 
}; 

function ViewModel() { 
    var self = this; 

    var testFcn = function() { 
     alert("In Function"); 
    }; 

    self.cards = ko.observableArray([]); 
    self.cardCount = ko.computed(function() { 
     return self.cards().length; 
    }); 
}; 

function Card() { 
    var self = this; 
    self.editing = ko.observable(false); 

    self.edit = function() { 
     self.editing(true); 
    }; 

    self.doneEdit = function() { 
     self.editing(false); 
    }; 
}; 

function createCard(data) { 
    var card = new Card(); 
    ko.mapping.fromJS(data, {}, card); 

    return card; 
}; 

var viewModel = new ViewModel(); 
function init() { 
    var mapping = { 
     "cards" : { 
      create : function(options) { 
       return createCard(options.data); 
      } 
     } 
    }; 

    ko.mapping.fromJS(cardsJSON, mapping, viewModel); 
}; 

init(); 
ko.applyBindings(viewModel); 

HTML

<table border="1"> 
    <thead> 
     <tr> 
      <th>Card</th> 
      <th colspan="2">Sides</th> 
      <th></th> 
     </tr> 
    </thead> 
    <tbody> 
     <!-- ko foreach: cards --> 
     <tr> 
      <td data-bind="text: cardName"></td> 
      <!-- ko foreach: sides --> 
      <td> 
       <span data-bind="text: $data, visible: !$parent.editing(), click: $parent.edit"></span> 
       <input data-bind="value: $data, visible:$parent.editing"></input> 
      </td> 
      <!-- /ko --> 
      <td><input value="Done" type="button" data-bind="click: doneEdit"></input></td> 
     </tr> 
     <!-- /ko --> 
    </tbody> 
</table> 

的代码可能会有点比它应该精心制作的,但服务的宗旨更好的解释。

正如你所看到的,有一个独立的视图模型来表示一个卡片,它包含了自己的属性,如“编辑”,“编辑”等。当我们通过映射插件映射JSON时,我们覆盖卡片是如何创建。我们基本上做的是创建卡片视图模型并应用映射,以便它包含预定义的属性以及JSON中的属性。

这必须明确地做(根据我的理解)。完成映射后,根视图模型将包含一个可观察的卡片数组,每个卡片实例都包含自己的“编辑”功能和可在数据绑定中使用的“编辑”属性。

希望这会有所帮助。