Это связано с другим вопросом, который я разместил 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. Я просто смущен, почему мне пришлось пройти через этот путь и почему этот первый способ, похоже, не сработал?
Непонятно, что такое 'searchResult'. Вы можете вставить свой полный код просмотра? – Ingro
@Ingro спасибо за вашу помощь. Я только что обновил сообщение выше с моим полным кодом просмотра. 'searchResult' представляет собой простую модель Backbone. –
Я не уверен, что это так, но вы можете попробовать использовать метод привязки подчеркивания для установки правильного контекста: 'searchResult.on" change: params ", _.bind (@setSidebarContent, @)' – Ingro