2013-07-14 3 views
1

Это связано с другим вопросом, который я разместил here, но он все еще ошеломляет меня.Правильное использование Backbone listenTo изнутри; Регион марионетки не определен?

У меня есть простой экземпляр модели, называемый searchResult, что я отлично работаю в своем представлении.

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

По какой-то причине, когда я внутри мнение, этот код не правильно работать, хотя кажется он должен:

View Code:

define [ 
     'backbone.marionette', 
     "jquery", 
     "underscore", 
     "backbone", 
     'text!globalTemplates/sidebar.html', 
     "global/models/sidebar", 
     "global/views/categories", 
     "global/collections/categories", 
     "global/views/stores", 
     "global/collections/stores", 
     'search/models/search-results' 
    ], (Marionette, $, _, Backbone, SidebarTemplate, SidebarModel, categoriesView, categoriesCollection, storesView, storesCollection, SearchResult) -> 
     class SidebarLayout extends Marionette.Layout 

     template:     _.template SidebarTemplate 
     id:      'sidebar' 
     className:    'js-sidebar marionette-layout' 
     tagName:     'aside' 

     regions: 
      form:     'form' 
      categoriesList:   '#categories-list' 
      storesList:    '#stores-list' 

     ui: 
      searchInput:   "input.search" 
      logo:     "strong#logo a" 
      lower:     ".lower" 
      top:     ".top" 

     events: 
      "click strong#logo a": "goHome" 
      "submit .top form":  "search" 
      "click button.submit": "search" 
      # "keyup input.search": "quickSearch" 

     initialize: (opts) -> 
      @router = opts.router 

      # event triggers 
      @on "sidebar:finished", @resize, @ 

      # override the categories display event 
      @categoriesList.open = (view) -> 
      this.$el.hide() 
      this.$el.html(view.el) 
      this.$el.slideDown(250, "easeOutExpo") 

      # override the stores display event 
      @storesList.open = (view) -> 
      this.$el.hide() 
      this.$el.html(view.el) 
      this.$el.slideDown(250, "easeOutExpo") 

      # override the categories remove event 
      @categoriesList.remove = (view) -> 
      this.$el.html(view.el) 
      this.$el.slideUp(250, "easeOutExpo", -> $(this).remove()) 

      # override the stores display event 
      @storesList.remove = (view) -> 
      console.log 'stores remove' 
      this.$el.slideUp(250, "easeOutExpo", -> $(this).remove()) 

     globalListeners: -> 

      # bind app vent and other global handlers 
      # app.vent.on "search:setParams", @setSearchInput 

      # SearchResult.on "change:params", @setSidebar, @ 

      # bind to changes to search params. 
      # SearchResult.listenTo @, "change:params", @setSidebar() 
      SearchResult.listenTo @, "change", @setSidebar() 
      # SearchResult.on "change:params", @render, @ 

     resize: => 
      sidebarHeight = @$el.height() 
      topHeight  = @ui.top.height() 
      @ui.lower.height(sidebarHeight - topHeight) 

     setSidebar: (input=true) => 
      # console.dir "SidebarLayout: setSidebarContent" 
      if input then @setSearchInput() 

      if SearchResult.get("params") 
      switch SearchResult.get("params").type 
       when "categories" 
        @setCategories() 
       when "text" 
        @setStores() 
        @setCategories() 

     setSearchInput: -> 
      if SearchResult.get("params")? 
      searchTerm = SearchResult.get("query") 
      @ui.searchInput.attr("value", searchTerm) 
      else 
      @ui.searchInput.attr("value", "") 

     setStores: -> 
      stores = new storesCollection() 
      stores.fetch 
      success: => 
       @storesView = new storesView 
       collection: stores 
       @storesList.show @storesView 
       @storesList.$el.prev("h3").show() 
       @trigger "sidebar:finished" 

     setCategories: -> 
      # console.log 'SidebarLayout: setCategories' 
      categories = new categoriesCollection() 
      categories.fetch 
      success: => 
       @categoriesView = new categoriesView 
       collection: categories 
       @categoriesList.show @categoriesView 
       @categoriesList.$el.prev("h3").show() 
       @trigger "sidebar:finished" 

     reset: => 
      @$el.css 
      "opacity": 0 
      "margin-left": "-500px" 

     slideSidebarIn: => 
      @$el 
      .animate 
      "opacity":1 
      "margin-left":0 
      , 500, -> app.reqres.setHandler "sidebar:visible", -> true 

     # CUSTOM EVENTS 

     goHome: (e) => 
      e.preventDefault() 
      # @router.navigate "/", trigger: true 
      # we're going to avoid using navigate, 
      # too complex to refactor at this point 
      window.location = "/" 

     quickSearch: => 
      # not working yet. 
      value = @ui.searchInput.val() 
      SearchResult.set("value", value) 

     search: (e) => 
      e.preventDefault() 
      value = @ui.searchInput.val() 
      app.router.navigate "search/#{value}?type=text", trigger: true 

     onBeforeRender: => 
      unless app.request("sidebar:visible") is true 
      @reset() 

     onRender: => 

      # console.dir 'SidebarLayout: render' 
      setTimeout => 
      @bindUIElements() 
      @globalListeners() 
      , 50 
      @$el.removeClass("hide") 
      if app.request("sidebar:visible") is false 
      @slideSidebarIn() 

проблема с этой линии:

searchResult.on "change:params", @setSidebarContent, @

я получаю эту ошибку:

Uncaught TypeError: Cannot call method 'show' of undefined

Я предполагаю, что это что-то делать с этим регионом не определен, или соответствующим контекстом не пропущен.

Таким образом, после тонн исследований и около 5 часов нонсенс, я читал на Документов для listenTo и, кажется, этот код должен работы:

@listenTo searchResult, "change:params", @setSidebarContent()

Единственный способ, которым я был на самом деле в состоянии заставить его работать, однако, в том, чтобы сделать это точный код:

searchResult.listenTo @, "change:params", @setSidebarContent()

Итак, у меня он работает сейчас, и beautif ully. Я просто смущен, почему мне пришлось пройти через этот путь и почему этот первый способ, похоже, не сработал?

+0

Непонятно, что такое 'searchResult'. Вы можете вставить свой полный код просмотра? – Ingro

+0

@Ingro спасибо за вашу помощь. Я только что обновил сообщение выше с моим полным кодом просмотра. 'searchResult' представляет собой простую модель Backbone. –

+1

Я не уверен, что это так, но вы можете попробовать использовать метод привязки подчеркивания для установки правильного контекста: 'searchResult.on" change: params ", _.bind (@setSidebarContent, @)' – Ingro

ответ

4

Удалите () после @setSidebarContent - это тоже меня достало.

@listenTo searchResult, "change:params", @setSidebarContent 
Смежные вопросы