Marionette CompositeView 为 Collection 中的每个模型呈现自身,而不是 ItemView (Marionette Rails)
Posted
技术标签:
【中文标题】Marionette CompositeView 为 Collection 中的每个模型呈现自身,而不是 ItemView (Marionette Rails)【英文标题】:Marionette CompositeView renders itself for each Model in Collection instead of ItemView (Marionette Rails) 【发布时间】:2013-10-08 06:38:51 【问题描述】:基本上,我试图将 CompositeView 呈现为带有表头的简单四列列表,其中集合中的每个模型都呈现为 a 并附加到 .我非常密切地关注an example of Derick's,只有一点点变化,但不幸的是得到了一些非常奇怪的结果。
视图不是渲染每个 itemView,而是引用自身并为集合中的每个项目重新渲染,生成一个新的表和表头。在此之前,它是在自己渲染compositeView。
我有一个 itemView,它的模板是一组项目,以及一个引用它的复合视图,它是一个表
复合视图:
class App.module('Views.Parts').Index extends Backbone.Marionette.CompositeView
template: 'parts/index'
itemView: App.Views.Parts.Part
tagName: 'table'
itemViewContainer: 'tbody'
appendhtml: (collectionView, itemView, index)->
collectionView.$el.append(itemView.el)
ItemView:
class App.module('Views.Parts').Part extends Backbone.App.ItemView
tagName: 'tr'
template: 'parts/part'
events:
"click .destroy": "destroy"
destroy: (e) ->
e.preventDefault()
@model.destroy()
onRender: ->
@stickIt()
控制器
class App.Controllers.Parts
constructor: ->
@parts = new App.Collections.Parts
@parts.reset(App.parts)
App.parts = null
showView: (view)->
App.mainRegion.show view
index: ->
view = new App.Views.Parts.Index
collection: @parts
@showView view
我还听说有必要在 CompositeView 之前声明一个 ItemView ——但是由于它是一个 Marionette Rails 项目,因此视图实际上位于不同的目录中。我是否必须声明它们的顺序或以其他方式将它们相互绑定?
【问题讨论】:
【参考方案1】:TL;DR Marionette.CompositeView 如果未定义,则将其自身用作项目视图类型。在原型上设置 itemView 属性以使其使用正确的项目视图
问题
在我们的案例中,问题是 Marionette 通过 following logic 获取 CompositeView 的 ItemView:
getItemView: function(item)
var itemView = Marionette.getOption(this, "itemView") || this.constructor;
if (!itemView)
throwError("An `itemView` must be specified", "NoItemViewError");
return itemView;
我们将 CompositeView 定义为:
class sm.Views.GreetingPicker extends Marionette.CompositeView
template: 'greeting_picker'
el: '.message-choice'
itemView: sm.Views.WelcomeMessage
当 CompositeView、ItemView 和 Layout 将它们捆绑在一起时(由 Rails 使用 Sprockets 提供服务),文件加载一下子就没有问题了。
在我拆分 Layout、CompositeView 和 ItemView 之后,CompositeView 的 appendHtml 的两个参数都是与 CompositeView 的类型相同。这是因为开头提到的木偶逻辑造成的。
解决方案
在初始化程序中手动设置构造函数的 itemView 属性。像这样:
class sm.Views.GreetingPicker extends Marionette.CompositeView
initialize: ->
@constructor::['itemView'] = sm.Views.WelcomeMessage
【讨论】:
谢谢!我刚刚解决了一个类似的问题,自然而然地在我发布我的问题后就遇到了这个解决方案。【参考方案2】:您不想拥有itemViewContainer
和appendHtml
。尝试删除后者,您的视图应该会正确呈现。
【讨论】:
谢谢。我们最终通过修复了渲染问题的 require 树更改了声明顺序(表格有效!)。我们仍然拥有itemViewContainer
和appendHtml
。这可能会在以后导致什么样的问题?
对于初学者来说,您的 appendHtml 代码对应于默认行为,因此不需要它。这可能会导致问题,因为它们都在告诉集合视图在哪里添加新的项目视图,这可能会导致冲突。
只是写信确认取出 appendHtml 代码仍然按预期呈现一切。感谢您的提示!以上是关于Marionette CompositeView 为 Collection 中的每个模型呈现自身,而不是 ItemView (Marionette Rails)的主要内容,如果未能解决你的问题,请参考以下文章
使用backbone.marionette获取“NoTemplateError:找不到模板”
CoffeeScript/Backbone/Marionette - 教程示例转换和范围问题