Как отправить модель, по которой щелкнули в ItemView, в другой ItemView, который находится на той же странице?

У меня есть коллекция инструментов, отображаемая как CompositeView. Каждый из отображаемых элементов в этой коллекции является ItemView. Имя региона, в котором они хранятся, называется toolNameRegion.

У меня есть еще один регион с именем toolDetailsRegion на этой странице, и он должен отображать атрибуты выбранного инструмента в toolNameRegion.

Вот вид:

@Tools.module "AboutApp.Show", (Show, App, Backbone, Marionette, $, _) ->

  class Show.Layout extends Backbone.Marionette.Layout
    template: JST['backbone/apps/about/templates/about']

    regions:
      toolNameRegion:  "#tool-name"
      toolDetailsRegion: "#tool-details"

  class Show.Tool extends Backbone.Marionette.ItemView
    template: JST['backbone/apps/about/templates/_tool']
    tagName: "li"

    events:
      "click a.tool-link" : -> 
        @trigger "tool-name:link:clicked", @model # How the hell do I pass this to the Show.ToolDetail class?
        console.log @model # shows the model attributes that was clicked

  class Show.Tools extends Backbone.Marionette.CompositeView
    template: JST['backbone/apps/about/templates/tools']
    itemView: Show.Tool
    itemViewContainer: "ul"

    triggers:
      "click .tool-link" : "tool:link:clicked"

  class Show.ToolDetail extends Backbone.Marionette.ItemView
    template: JST['backbone/apps/about/templates/tool_details']
    itemView: Show.Tool

    onShow: -> console.log "onShow"
    onClose: -> console.log "onClose"

Вот контроллер:

@Tools "AboutApp.Show", (Show, App, Backbone, Marionette, $, _) ->

  Show.Controller =

    showAbout: ->
      tools = App.request "get:tools"
      @aboutLayout = @getAboutLayout()

      @aboutLayout.on "show", =>
        @showTools tools
        @showInitialTool tools

      App.mainRegion.show @aboutLayout

    showTools: (tools) ->
      toolsView = @getToolsView tools   
      console.log toolsView

      toolsView.on "tool:link:clicked", (tool) =>
        console.log "model: #{tool}"
        tool = @getInitialToolView tool
        @aboutLayout.toolDetailsRegion.show tool

    @aboutLayout.toolNameRegion.show toolsView


  getToolsView: (tools) ->
    new Show.Tools
      collection: tools

  showInitialTool: (tools) ->
    initial_tool = tools.at(1) 
    toolView = @getInitialToolView initial_tool
    @aboutLayout.toolDetailsRegion.show toolView

  getToolDetailsView:  ->
    App.request "tool:detail:view"

  toolDetailsRegion: ->
    toolDetailView = @getInitialToolView 
    @about.toolDetailsRegion.show toolDetailView

  getInitialToolView: (tool) ->
    new Show.ToolDetail
      model: tool

  getAboutLayout: ->
    new Show.Layout

Как передать @model (модель, на которую нажали) контроллеру, чтобы @model можно было передать в класс представления Show.ToolDetail, чтобы можно было динамически обновлять toolDetailsRegion?

Вот мои сущности (ресурсы):

@Tools.module "Entities", (Entities, App, Backbone, Marionette, $, _) ->

  class Entities.Tool extends Backbone.Model

  class Entities.ToolCollection extends Backbone.Collection
    model: Entities.Tool
    url: -> Routes.tools_path()

  API =

    setTools: (tools) ->
      new Entities.ToolCollection (tools)

    getToolEntities: ->
      tools = new Entities.ToolCollection()
      tools.fetch
        reset: true
      tools

    App.reqres.setHandler "set:tools", (tools) ->
      API.setTools tools

    App.reqres.setHandler "tool:entities", ->
      API.getToolEntities()

Спасибо за ваш ответ @David Sulc. Он по-прежнему не передает модель. Может я не правильно форматирую?

То, как я беру модель из представления:

class Show.Tool extends Backbone.Marionette.ItemView
  template: JST['backbone/apps/about/templates/_tool']
  tagName: "li"

  events:
    "click a.tool-link" : -> 
      App.request "get:new:tool", @model
      console.log @model

В контроллере:

 showTools: (tools) ->
    toolsView = @getToolsView tools   
    console.log toolsView

    toolsView.on "tool:link:clicked", (tool) =>
      console.log "model retrieved from click: #{tool}" # comes up undefined; how to obtain?
      tool = App.request "get:new:tool" # could this be the path, but since tool is undefined, won't work? 
      new_tool = @getInitialToolView tool
      @aboutLayout.toolDetailsRegion.show new_tool

  @aboutLayout.toolNameRegion.show toolsView

Спасибо @David Sulc за то, что показал мне путь!

В контроллере:

  showTools: (tools) ->
    toolsView = @getToolsView tools   
    console.log toolsView

    Tools.AboutApp.Show.on "tool-name:link:clicked", (tool) =>
      console.log tool.get('name')
      new_tool = @getInitialToolView tool
      @aboutLayout.toolDetailsRegion.show new_tool 

В коде представления:

  class Show.Tool extends Backbone.Marionette.ItemView
    template: JST['backbone/apps/about/templates/_tool']
    tagName: "li"

    events:
      "click a.tool-link" : -> 
        Tools.AboutApp.Show.trigger "tool-name:link:clicked", @model
        console.log @model

  class Show.ToolDetail extends Backbone.Marionette.ItemView
    template: JST['backbone/apps/about/templates/tool_details']
    itemView: Show.Tool
    Tools.AboutApp.Show.on "tool-name:link:clicked", (tool) =>
      console.log tool

    onShow: -> console.log "onShow"
    onClose: -> console.log "onClose"

person Joe C    schedule 09.05.2013    source источник
comment
Спасибо за ответ. Будут ли эти события в масштабе приложения находиться в модуле инструментов? Или в контроллере? Или в макете?   -  person Joe C    schedule 10.05.2013


Ответы (1)


Вы можете использовать события, привязанные к вашему текущему модулю. Запустите событие в вашем представлении с помощью

Tools.AboutApp.Show.trigger "my:event", @model

Затем в вашем контроллере вы можете прослушать это событие и обновить другое представление:

Tools.AboutApp.Show.on "my:event", (model) ->
    console.log model

Синтаксис, который вы использовали в представлении Show.Tools, будет ограничен представлением элемента (и в определенной степени его представлением коллекции). Поскольку вам нужно передавать данные между разными представлениями, нам нужно расширить область действия и, следовательно, использовать вызов, как указано выше: запускать и прослушивать события в области Tools.AboutApp.Show.

На ваш взгляд:

events:
  "click a.tool-link" : -> 
    Tools.AboutApp.Show.trigger "tool-name:link:clicked", @model

И в вашем подробном представлении:

Tools.AboutApp.Show.on "tool-name:link:clicked", (tool) =>
  console.log "model retrieved from click: #{tool}"

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

person David Sulc    schedule 10.05.2013
comment
Спасибо за ваш ответ @David Sulc. Он по-прежнему не передает модель. - person Joe C; 10.05.2013
comment
Я обновил свой ответ. Не похоже, что вы используете правильную область событий, и ваши имена триггеров несовместимы. - person David Sulc; 10.05.2013
comment
вы правы насчет области действия, и код, который я привел выше, относится к именованию события с моей стороны. Я почти закончил, и как только я заработаю, я отмечу ответ как принятый. Спасибо за помощь! - person Joe C; 10.05.2013
comment
спасибо за помощь... модель проходит отлично, и ваш ответ помечен как приемлемый. Теперь мне нужно понять синтаксис, чтобы обновить представление сведений ... ха-ха - person Joe C; 10.05.2013