後でコードを管理できるように、ビューとモデルが独立して完全に分離されて動作することを確認することをお勧めします。
したがって、この場合、各ペットは 1 つまたは複数のお気に入りのスナックを持つことができます。したがって、基本的には、単一のスナック モデルではなく、ここでスナックのコレクションを期待しています。
そのため、別の Snacks コレクションを作成してからSnack Model
. 次に、別のビューを維持SnackListItem
し、リストを反復処理して、SnackCollection
各項目のビューをレンダリングします。
そのため、両方に個別のテンプレートを作成します
<div id="foo"></div>
<script type="text/template" id="pet-view-template">
<p> <span><b> Dog Name: </b> </span> <%= name %> </p>
<p> <span><b> Dog Color: </b></span> <%= color %> </p>
<h4> favorite snacks </h4>
<ul class="snacks-list">
</ul>
snack name: <input type="text" class="snack-name" />
cost : <input type="text" class="snack-cost" />
<button class="add-snack">add snack</button >
</script>
<script type="text/template" id="snack-view-template">
<b>snack name:</b> <span> <%=favorite_snacks %> </span> ::
<b>cost: </b><span> <%= favorite_snack_cost %> </span>
<b class="toggle-change"> Change </b>
<span class="modify-fields hide">
<b class="modify">snack name:</b> <input type="text" class="modify-name" data-key="favorite_snacks" />
<b class="modify">snack cost:</b> <input type="text" class="modify-cost" data-key="favorite_snack_cost" />
</span>
</script>
Snacks コレクション用に別のビューとモデルを作成しました。 これはまだ最適化できます。
Javascript
// Create a Dog Model
var Dog = Backbone.Model.extend({
defaults: {
name: 'New dog',
color: 'color'
}
});
// Create a collection of dogs
var Dogs = Backbone.Collection.extend({
model: Dog
});
// Create a model for Snacks
var Snack = Backbone.Model.extend({
defaults: {
favorite_snacks: 'bacon',
favorite_snack_cost: '52'
}
});
// Create a collection of Snacks
var Snacks = Backbone.Collection.extend({
model: Snack
});
// Define the model for a Dog
var dog = new Dog({
name: "Spot",
color: "white"
});
// Create a View for the Snack Item
var SnackItemView = Backbone.View.extend({
tagName : 'li',
className: 'snacks',
template: _.template($('#snack-view-template').html()),
initialize: function() {
// Need to bind to save the context of this to the view
_.bind('toggleChange', this);
// Need to listen to the Model change event and render the view again
// as the new data has to be reflected
this.listenTo(this.model, 'change' , this.render);
},
// Assign events for the fields inside Snacks view
events : {
'click .toggle-change' : 'toggleChange',
'change input' : 'modifyData'
},
toggleChange: function() {
var $change = $('.modify-fields', this.$el);
$change.hasClass('hide') ? $change.removeClass('hide') : $change.addClass('hide');
},
// This will captue the data from the inputs and trigger the change event on the model
modifyData: function(e) {
var value = $(e.currentTarget).val(),
key = $(e.currentTarget).data('key');
this.model.set(key,value);
},
render: function () {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
var PetView = Backbone.View.extend({
el: '#foo',
template: _.template($('#pet-view-template').html()),
initialize: function () {
this.collection = (this.collection && this.collection instanceof Backbone.Collection) || new Snacks(Snack);
},
events: {
'click .add-snack' : 'addSnack'
},
addSnack: function () {
// Render new snack Item
var newSnack = new Snack({
favorite_snacks: $('.snack-name', this.$el).val(),
favorite_snack_cost: $('.snack-cost', this.$el).val()
});
this.renderSnackView(newSnack);
// Clear the inputs
$('input', this.$el).val('');
},
// render each snack view
renderSnackView: function (snack) {
var snackView = new SnackItemView({
model: snack
});
$('.snacks-list', this.$el).append(snackView.el);
snackView.render();
},
render: function () {
var thisView = this;
// Append the PetView
this.$el.html(this.template(this.model.toJSON()));
// Iterate over each snack collection of the pet and render that item
_.each(this.collection.models, function (snack) {
thisView.renderSnackView(snack);
});
return this;
}
});
var petView = new PetView({
model: dog
});
petView.render();
動作中のフィドルを確認する
コードの一部を説明するためにコメントを使用しました。最近バックボーンを使い始めたばかりなので、バックボーンを最初に学ぶのは大変です。しかし、慣れると非常にシンプルでありながら強力です..これが役立つことを願っています:)
ただし、アプリケーションをビルドしようとするときは、メモリ リークを減らすために、使用されていないビューとイベントを破棄する必要があります。