这与我在这里发布的另一个问题有关,但它仍然让我难以置信。
我有一个简单的主干模型实例,称为searchResult
我在我看来工作得很好。
我基本上想做的很简单;随着此模型的更改,重置视图内的内容区域。
出于某种原因,当我在视图中时,此代码似乎无法正常工作,尽管它似乎应该:
查看代码:
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()
所以,我现在可以正常工作了,而且很漂亮。我只是很困惑为什么我必须通过这种方式通过它,为什么第一种方式似乎不起作用?