Я начну с четкого вопроса и объясню после:
Как правильно инкапсулировать модель, содержащуюся в CompositeView
, в ItemView
.
Моя проблема проста, но я не могу заставить что-то хорошее работать. У меня есть дерево заметок. Каждая заметка является Backbone.model и имеет коллекцию @descendants
, затем у меня есть Backbone.Collection для представления этого дерева (экземпляром которого является @descendants). Я устанавливаю базовую CollectionView
с CompositeView
в качестве itemView
. Все отрисовывалось отлично, чему я был очень рад. Это рабочее решение показано в первом фрагменте кода!
Вот в чем проблема. Опираясь на это, я столкнулся с этой проблемой: События, инициированные для всей иерархии, что имеет смысл для того, как мои события были привязаны. Сначала я просто добавлял уникальные селекторы (добавлял data-guid к своим html-элементам, чтобы я мог получить их по нему), и это работало нормально, хотя это уже становилось хакерским. Но возникла другая похожая проблема, поэтому я решил, что мне нужно решение для этого. Итак, сказал я себе, давайте инкапсулируем каждую модель в ItemView и используем составное представление для их рекурсивного рендеринга. Но... Это было не к лучшему во всех мирах...
Вот что у меня было в начале:
class Note.ModelView extends Marionette.CompositeView
template: "note/noteModel"
id: "note-item"
itemViewContainer: ".note-descendants"
ui:
noteContent: ".noteContent"
events:
"keypress .noteContent": "createNote"
"click .destroy": "deleteNote"
# ...
initialize: ->
@collection = @model.descendants
# ...
class Note.CollectionView extends Marionette.CollectionView
id: "note-list"
itemView: Note.ModelView
initialize: ->
@listenTo @collection, "sort", @render
Теперь я перенес все, что относится к рендерингу Модели, в новый ItemView.
class Note.ModelView extends Marionette.ItemView
template: "note/noteModel"
ui:
noteContent: ".noteContent"
events: ->
guid = @model.get 'guid'
events = {}
events["keypress #noteContent#{guid}"] = "createNote"
events["blur #noteContent#{guid}"] = "updateNote"
events["click #destroy#{guid}"] = @triggerEvent 'deleteNote'
initialize: ->
@bindKeyboardShortcuts()
@listenTo @model, "change:created_at", @setCursor
class Note.TreeView extends Marionette.CompositeView
template: "note/parentNote"
itemView: Note.ModelView
initialize: ->
@collection = @model.descendants
@listenTo @collection, "sort", @render
_.bindAll @, "renderItem"
renderItem: (model) ->
if model.get('parent_id') is 'root'
itemView = new Note.ModelView model: model
itemView.render()
@$el.append itemView.el
onRender: ->
@collection.each this.renderItem
@renderItem @model
appendHtml: (collectionView, itemView) ->
@model.descendants.each (note) =>
iv = new Note.ModelView model: note
iv.render()
@.$('.note-descendants').append iv.el
class Note.CollectionView extends Marionette.CollectionView
id: "note-list"
itemView: Note.TreeView
initialize: ->
@listenTo @collection, "sort", @render
и шаблон noteMode (parentNote сейчас просто пустой шаблон)
<button class="btn btn-danger btn-xs untab">UN</button>
<button class="btn btn-success btn-xs tab">TAB</button>
<div class="noteContent">{{{indent}}}{{{title}}}</div>
<button class="destroy"></button>
<div class="note-descendants"></div> # That is where I'm putting the children notes
Так что это почти работает. Но это хаки и ... ну, это все еще не совсем работает. Я прочитал всю документацию, и я прочитал эти две ссылки Дерик Бейли о вложенной структуре и CompositeView и Дэвид Сульк о вложенных представлениях, но я все еще чувствую, что упускаю некоторые важные детали.
В качестве ответа я ищу любой намек или любой общий способ справиться с этим с помощью Marionette. Я действительно ищу что-то чистое, так как это будет одна из угловых частей, на которых будет построено приложение.
Может быть, я ищу не в том месте? Все будет приветствоваться!! Большое Вам спасибо
Я желаю вам всем очень приятной ночи. Спасибо за уделенное время.
>
, чтобы проверять только события DOM, происходящие с прямыми потомками? Если вам этого недостаточно, я бы предпочел решить проблему на стороне распространения событий: остановить всплытие событий в вашем рекурсивном представлении. 09.10.2013views.el
. Вот почему я хотел попробовать это решение. Селекторы прямых потомков выполняют свою работу, но, как показано в первой ссылке, которую я разместил в своем вопросе, Дерик Бейли решает эту проблему с помощью ItemView, инкапсулирующего все (на самом деле, это только базовое представление, но оно эмулирует поведение ItemView) . Вот что побудило меня попытаться реорганизовать CompositeView! Кроме того, у меня есть сочетание клавиш, для которого требуется e.stopPropagation(), и я не знаю, может ли это быть долгосрочным решением. 10.10.2013