[英]Multiple view on same page with backbone.js
I am testing backbone by making a craft system. 我正在通过制作工艺系统来测试骨干。 You have elements (stone, wood, gold..) and you make items with it.
您拥有元素(石头,木头,黄金..),并用它制作物品。
To make items, you have some recipe, so I have two models: 要制作物品,您需要一些食谱,所以我有两个模型:
Recipe
Element
At the bottom of my page, I make a list of my elements using a backbone view. 在页面底部,我使用主干视图列出了我的元素。 It work very well.
效果很好。 When you click on an element, I add it to my bag.
当您单击某个元素时,我会将其添加到我的包中。
My root router : 我的根路由器:
class MyTest.Routers.App extends Backbone.Router
routes:
'': 'index'
'elements/:id' : 'show'
initialize: ->
@elements = new MyTest.Collections.Elements()
@elements.fetch()
index: ->
view = new MyTest.Views.ElementsIndex(collection: @elements)
$('#elements').html(view.render().el)
@initRecipe()
initRecipe: ->
@recipes = new MyTest.Collections.Recipes()
@recipes.fetch()
view = new MyTest.Views.RecipesIndex(collection: @recipes)
$('#recipes').html(view.render().el)
show: (id) ->
alert "Element #{id}"
My element view : 我的元素视图:
class MyTest.Views.Element extends Backbone.View
template: JST['elements/element']
events:
'element_rended': 'initImagesDatas'
'click img' : 'observeImageEvents'
'click .more': 'addToBag'
'click .less': 'decreaseNumber'
tagName : 'li'
render: ->
$(@el).html(@template(element: @model))
@currentImage = $(@el).find('img')
@craftBox = null
$(@el).trigger('element_rended')
this
initImagesDatas: ->
@currentImage.data('alreadyAdded',false)
@currentImage.data('position',false)
observeImageEvents: (event) ->
event.preventDefault()
$(event.target).parent().next('div.element-description').fadeToggle()
isAdded: ->
if (@currentImage.data('alreadyAdded') == true) then true else false
addToBag: (event) ->
if (@isAdded())
@incrementNumber()
else
@getNextCraftBox().append(@currentImage.clone())
@currentImage.data('alreadyAdded',true)
@incrementNumber()
getNextCraftBox: ->
returnItem = $('#craft-area li').eq(0)
$('#craft-area li').each ->
if $(this).find('img').length == 0
returnItem = $(this)
return false
@craftBox = returnItem
return returnItem
incrementNumber: ->
@craftBox.find('.number').show()
@craftBox.find('.number').text(parseInt(@craftBox.find('.number').text())+ 1)
decreaseNumber: ->
if parseInt(@craftBox.find('.number').text()) == 1
@removeToBag()
else
@craftBox.find('.number').text(parseInt(@craftBox.find('.number').text())- 1)
removeToBag: ->
if (@isAdded())
@craftBox.parents('ul').append('<li><div class="number">0</div></li>')
@craftBox.remove()
@currentImage.data('alreadyAdded',false)
My recipe view : 我的食谱视图:
class MyTest.Views.Recipe extends Backbone.View
recipeSelected: null
template: JST['recipes/recipe']
tagName : 'li'
className: 'recipe-li',
events:
'click': 'preFillItemsRequired'
preFillItemsRequired: ->
if $(@el).hasClass('selected') then $(@el).removeClass('selected') else $(@el).addClass('selected');
recipeSelected = @model;
@addIngredient()
addIngredient: ->
console.log('pass')
render: ->
$(@el).html(@template(recipe: @model))
this
My question is how can I interact between my two views? 我的问题是我如何在两个视图之间进行交互? How can I get my selected recipe (without using css selector) from my element's view for example?
例如,如何从元素视图中获取选择的配方(不使用CSS选择器)?
My test looks like: 我的测试看起来像:
The easiest and the propert MVC way to do it is having them to observe the same model. MVC最简便的方法是让他们观察相同的模型。
A view should not be able to interact with another view, but it should be able to observe a model and change the model state, or change its own state based on the model state. 一个视图应该不能与另一个视图交互,但是它应该能够观察模型并更改模型状态,或者根据模型状态更改其自身的状态。
var MyTest.Views.Recipe = Backbone.View.extend({
initialize: function(){
this.model.on('change:selected', this.render, this);
},
events: {
'click': function(){
this.model.set('selected', this.cid);
}
},
render: function(){
if( this.model.get('selected') == this.cid ) {
this.$el.addClass('selected')
}
else {
this.$el.removeClass('selected')
}
}
});
var model = new Backbone.Model();
var view1 = new MyTest.Views.Recipe({
model: model,
});
var view2 = new MyTest.Views.Recipe({
model: model,
})
// ...
I think the easiest way is to use the event triggers 我认为最简单的方法是使用事件触发器
http://lostechies.com/derickbailey/2011/08/30/dont-limit-your-backbone-apps-to-backbone-constructs/ http://lostechies.com/derickbailey/2011/08/30/dont-limit-your-backbone-apps-to-backbone-constructs/
shows the thought at the bottom 在底部显示思想
or the simpler usage pattern 或更简单的使用模式
https://github.com/derickbailey/backbone.marionette and look at app.vent: Event Aggregator https://github.com/derickbailey/backbone.marionette并查看app.vent:Event Aggregator
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.