2012-03-01 3 views
2

Я тестирую основу, создавая систему кораблей. У вас есть элементы (камень, дерево, золото ..), и вы делаете предметы с ним.Множественный просмотр на той же странице с backbone.js

Для того, чтобы предметы, у вас есть какой-то рецепт, так что у меня есть две модели:

Recipe 
Element 

В нижней части моей страницы, я делаю список моих элементов, используя вид магистральную. Он работает очень хорошо. Когда вы нажимаете на элемент, я добавляю его в свою сумку.

корень мой маршрутизатор:

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}" 

мой взгляд элемент:

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) 

мой взгляд рецепт:

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 

Мой вопрос, как я могу взаимодействовать между двух моих взглядов? Как я могу получить свой выбранный рецепт (без использования селектора css), например, из представления моего элемента?

Мой тест выглядит следующим образом:

My interface

ответ

1

Я думаю, что самый простой способ заключается в использовании триггеров событий

http://lostechies.com/derickbailey/2011/08/30/dont-limit-your-backbone-apps-to-backbone-constructs/

показывает мысль в нижней

или более простой шаблон использования

https://github.com/derickbailey/backbone.marionette и посмотреть на app.vent: Event агрегатор

+0

На самом деле, чем больше я смотрю на него, тем лучше для вас может быть, имея только модель selectedRecepie либо из списка рецептов или отдельной модели, как можно просмотреть – MarkKGreenway

+0

Спасибо, но если я использовать триггера событий, я должен уволить его из моей модели рецепта, когда я его выбрал, и как я могу его поймать на моей модели элементов? – Sebastien

3

Самый простой и Свойс MVC способ сделать это иметь их соблюдать ту же модель.

Вид не должен взаимодействовать с другим видом, но он должен иметь возможность наблюдать за моделью и изменять состояние модели или изменять собственное состояние на основе состояния модели.

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, 
}) 

// ... 
+0

И как я могу наблюдать или взаимодействовать между моделями? – Sebastien

+0

Позвольте мне изменить свой ответ и пояснить себя –

+0

Спасибо, но я имею в виду ... Если я хочу поймать событие рецепта из моей модели элемента, как я могу это сделать? – Sebastien

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