Я пытаюсь понять, как лучше всего общаться между различными компонентами проекта Backbone. Я повторно реализовал Backbone-версию TodoMVC, и мой вопрос касается удаления моделей из объекта коллекции.
Я понимаю, что экземпляры модели Backbone инициируют событие изменения всякий раз, когда любое из его свойств модели изменяется с помощью .set()
, и что представление, связанное с экземпляром модели, должно .listenTo()
измениться по сравнению с экземпляром модели, а затем выполнить повторную визуализацию. Однако как лучше всего организовать связь между моделями и объектом коллекции, в котором они размещены? Например, как должна работать связь, когда модель удаляется из объекта коллекции?
Вот что я думаю: когда модель удаляется, я думаю, что экземпляр модели должен генерировать пользовательское событие, которое прослушивает объект коллекции, и передавать себя. Когда объект коллекции получает это событие, он должен удалить экземпляр модели из списка (вместе со всеми прослушивателями событий, прикрепленными к модели), а затем весь объект коллекции должен повторно отобразить себя. Этот процесс повторного рендеринга затем создаст новый набор моделей и представлений моделей.
Это лучший подход? Я хотел бы услышать ваш вклад! Для меня этот процесс повторного рендеринга кажется очень дорогим, поскольку вам придется уничтожить существующие элементы DOM, удалить их прослушиватели событий, а затем снова создать их заново.
ОБНОВЛЕНИЕ – 26 марта 2015 г.
Чтобы сделать это более конкретным, я включу код, который у меня есть до сих пор, и укажу, где, по моему мнению, я не понимаю.
Структура файла
коллекции
а. todoList.coffee
модели
а. todo.coffee
взгляды
а. todoView.coffee
б. todoListView.coffee
приложение.кофе
app.coffee
window.app = app = window.app || {}
data = [
{
title: 'Eat dinner',
completed: false
}
{
title: 'Go to gym',
completed: true
}
]
app.todos = data.map (todo) -> new app.Todo todo
app.todoList = new app.TodoList app.todos
app.todoListView = new app.TodoListView
collection: app.todoList
app.$app = $('#todo-app')
$('#todo-app').append app.todoListView.render().el
todo.coffee
window.app = app = window.app || {}
app.Todo = Backbone.Model.extend
defaults:
title: ''
completed: false
toggleComplete: ->
this.set 'completed', !this.get 'completed'
todoList.coffee
window.app = app = window.app || {}
app.TodoList = Backbone.Collection.extend
model: app.Todo
initialize: () ->
# This is what I don't like - creating 'remove-todo' event
this.on 'remove-todo', this.removeTodoFromList
removeTodoFromList: (model) ->
this.remove model
getCompleted: ->
this.filter (model) -> model.completed
getNotCompleted: ->
this.filter (model) -> !model.completed
todoView.coffee
window.app = app = window.app || {}
app.TodoView = Backbone.View.extend
tagName: 'li'
events:
'click input' : 'checkComplete'
'click .delete' : 'removeTodo'
checkComplete: (e) ->
this.model.toggleComplete()
removeTodo: (e) ->
# I don't like how the collection is listening for this custom event 'remove-todo'
this.model.trigger 'remove-todo', this.model
initialize: ->
this.listenTo this.model, 'change:completed', () ->
this.render()
render: ->
template = _.template $('#todo-view').html()
this.$el.html template this.model.toJSON()
return this
todoListView.coffee
window.app = app = window.app || {}
app.TodoListView = Backbone.View.extend
tagName: 'ul'
className: 'todo-list'
initialize: ->
this.collection.on 'remove', (() ->
this.resetListView()
this.render()
), this
addOne: (model) ->
todoView = new app.TodoView
model: model
this.$el.append todoView.render().el
resetListView: ->
this.$el.html('')
render: ->
_.each this.collection.models, ((model) -> this.addOne model), this
return this
Объяснение кода
Как вы можете видеть в моих комментариях выше, всякий раз, когда происходит щелчок по кнопке удаления, мой todoView запускает пользовательское событие «удалить-todo». Коллекция todoList прослушивает это событие и удаляет конкретную модель из коллекции. Поскольку событие «удалить» запускается всякий раз, когда коллекция удаляет модель, todoListView прослушивает это событие «удаления», а затем выполняет повторную визуализацию. Я чувствую, что я где-то пропал. Есть совет?