TL; DR : Если я опрашиваю всю коллекцию моделей с сервера, как я могу объединить измененные атрибуты в каждую модель и добавить / удалить добавленные / удаленные модели из коллекции?
В своем базовом приложении я опрашиваю всю коллекцию моделей. У меня есть Backbone.Collection
, который я в основном называю reset
каждый раз, когда получаю массив моделей, поэтому:
myCollection.reset(server_response);
Единственная проблема с этим состоит в том, что он избавляется от старых моделей, отчасти устраняя выгоду событий на модели. Это, конечно, цель reset
, но я хочу лишь изменить измененные атрибуты моделей и удалить модели, отсутствующие в ответе, и добавить модели, которые были в ответе, но не в коллекции.
По сути, я хочу что-то вроде объединения данных.
Для моделей, которые уже есть в ответе и в коллекции, я думаю, что я могу просто сделать model.set(attributes)
, и он позаботится о set
только о тех, которые действительно изменились, вызывая события change
в процессе. , Это здорово.
Но как мне справиться со случаями, когда модели были в ответе, но уже не в коллекции, и наоборот, не в ответе, а в коллекции?
Мое предлагаемое решение
Я не знаю, есть ли у магистрали способ сделать это, и я, может быть, слишком усложняю, поэтому и спрашиваю, но тогда я думал о создании метода в моей коллекции, который получает server_response
.
Он получит все атрибуты id
server_response
и все атрибуты id
моделей, уже находящихся в коллекции.
Разница id
в ответе - сбор будет = добавление моделей, и наоборот будут удалены модели. Добавьте и удалите эти модели соответственно из коллекции.
Пересечение обоих наборов id
будет модифицированными моделями, так что итерируйте эти id
и просто выполните collection.get(id).set(attributes)
.
В псевдокофекте:
merge: (server_response) =>
response_ids = _.pluck(server_response, 'id')
collection_ids = @pluck('id')
added = _.difference(response_ids, collection_ids)
for add in added
@add(_.find(server_response, (model) ->
return model.id == add
))
removed = _.difference(collection_ids, response_ids)
for remove in removed
@remove(@get(remove))
changed = _.intersection(response_ids, collection_ids)
for change in changed
@get(change).set(_.find(server_response, (model) ->
return model.id == change
))