Backbone.js — Как обрабатывать несколько моделей с одинаковым идентификатором и типом? Или как избежать такой ситуации

Недавно я столкнулся с несколькими ситуациями, когда у меня есть несколько представлений на странице, которые должны поддерживаться одной моделью. Таким образом, просто изменив модель, все соответствующие виды автоматически обновят свой внешний вид. Проблема в том, что для достижения этого АТМ мне нужно было бы написать код, который активно ищет эти модели. Иногда мне везет, и модель предоставляется мне через обработчик событий, но обычно это не так. Я ищу хороший способ иметь один экземпляр модели на странице за раз, а затем просто ссылаться на эту модель повсюду. Как люди обычно справляются с этой потребностью? Backbone-relational справляется с этим, сохраняя центральное хранилище с помощью lawnchair.js, и я слышал о людях, использующих единую глобальную коллекцию для ведения реестра всех моделей.


person JayD3e    schedule 20.12.2012    source источник
comment
Будет ли это так же просто, как иметь родительское представление, которое обрабатывает модель и визуализирует дочерние представления, перерисовывая их при изменении модели?   -  person Mathletics    schedule 21.12.2012
comment
Находятся ли просмотры на одной и той же странице (один и тот же маршрут)?   -  person Lukas    schedule 21.12.2012
comment
Математика: в моем случае это не сработает, потому что у меня есть несколько совершенно разных представлений, которые должны поддерживаться одной и той же моделью. Лукас: да, они на одной волне.   -  person JayD3e    schedule 21.12.2012


Ответы (1)


Короткий ответ:

Одна модель, совместно используемая несколькими представлениями (которые вы могли бы назвать «дубликаты моделей»), на самом деле является вполне допустимым (и полезным) шаблоном Backbone; это вообще не проблема. Из того, что я могу сказать, проблема заключается в том, что эту модель трудно представить в нескольких представлениях, и поэтому я бы предложил вместо этого решить эту проблему.

Подробный ответ:

Проблема с передачей модели в несколько представлений заключается в том, что она по своей сути связывает представления вместе (чтобы предоставить эту общую модель каждому представлению, родительское представление также должно иметь эту модель, как и любые «промежуточные» представления). Теперь, как программистов, нас учат держать вещи как можно более инкапсулированными, поэтому поначалу связывание представлений может показаться «неправильным». Тем не менее, парные представления на самом деле желательны: главное правильно ограничить какие представления связаны.

@Shauna предложила для этого отличное эмпирическое правило: «представление заботится только о себе и создает своих детей». Если вы будете следовать этому правилу, связь между вашими представлениями не станет проблематичной, и вы сможете создавать гибкий, удобный для сопровождения код (намного более удобный, чем если бы вы использовали глобальные переменные, поскольку тогда вы бы действительно потерять инкапсуляцию).

В свете всего этого давайте рассмотрим быстрый пример. Допустим, у вас есть представления A, B и C, которые используют модель X, но вы строите A, B и C в совершенно разных местах кода (что затрудняет совместное использование X между ними).

1) Во-первых, я бы посмотрел, почему A, B и C строятся в таких разных местах, и посмотрел, нельзя ли сдвинуть их ближе друг к другу.

2) Если они должны быть построены так далеко друг от друга, я бы посмотрел, есть ли у них что-то общее, что я могу использовать; например, все ли эти точки имеют общий объект? Если это так, то, возможно, мы можем поставить X на этот объект, чтобы поделиться им со всеми нашими представлениями.

2) Если нет никакой связи ни в размещении кода, ни в общих переменных между A, B и C, тогда мне придется спросить: «Должен ли я вообще делить модель между ними?»

Скучная история об авторе:

Когда я впервые начал использовать Backbone, мне часто приходилось спорить с коллегами, потому что я хотел создать глобальные переменные, а они были категорически против этого. Я пытался объяснить им, что если бы я не мог использовать глобальные переменные, мне пришлось бы передавать модели из представления A в представление B, в представление C, в представление D, в представление E, тогда как эта модель действительно нужна только E. Такая трата!

За исключением того, что (как я потом узнал), я ошибался. Глобальные объекты — ужасная идея, по крайней мере, с точки зрения ремонтопригодности. Как только вы начнете их использовать, вы быстро не поймете, какой код на что влияет, потому что вы потеряете инкапсуляцию, которую обычно имеете между представлениями, использующими эту глобальную переменную. И если вы работаете над значительным проектом (т. е. таким, для которого стоит использовать Backbone), инкапсуляция — это единственный способ сохранить ваш код в порядке.

Много раз пользовавшись Backbone в промежутке между ними, я теперь твердо уверен, что правильный ответ — передать вашу модель вашему представлению по мере ее создания. Это может означать передачу моделей между промежуточными представлениями, которые не используют их напрямую, но это даст вам гораздо лучший, более удобный для сопровождения код, чем если бы вы передавали модели через глобальные переменные. Как бы неловко это ни казалось поначалу, передача моделей в представления при их создании является правильной практикой.

Как только вы поближе познакомитесь с Backbone, вы, вероятно, обнаружите, что вам очень редко нужно передавать модель через более чем одно промежуточное представление. Фактически, вы, вероятно, заметите, что всякий раз, когда вам приходится передавать модель между несколькими представлениями, вы обнаруживаете «запах кода», и что реальная проблема заключается в том, что ваш код нуждается в рефакторинге.

Но, как и во всем остальном на Stack Overflow, ваш пробег может отличаться ;-)

person machineghost    schedule 20.12.2012
comment
Полностью согласен с этим. Я также научился передавать модель непосредственно в представление при создании. Это дизайнерское решение, к которому я очень строго отношусь, так как оно приводит к меньшей путанице в будущем. Тем не менее, это все еще не совсем ответ на мой вопрос. Вы по-прежнему можете явно передать модель в представление после ее получения из глобального реестра моделей. Главный момент заключается в том, что я пытаюсь найти хороший способ избежать дублирования моделей (моделей с одинаковым идентификатором) на странице. - person JayD3e; 21.12.2012
comment
Я не могу говорить о каждой ситуации, но, основываясь на моем опыте создания довольно надежного сайта Backbone, я не думаю, что дублирование моделей является проблемой. Что ж, если бы у вас действительно было несколько идентичных моделей, это было бы проблемой, но дублирование в одной модели, разделяемой несколькими представлениями, на самом деле является совершенно допустимым (и полезным) шаблоном, а не проблемой. Из того, что я могу сказать, ваша проблема заключается в том, что эту модель трудно представить в нескольких представлениях, и поэтому я бы предложил посмотреть, можете ли вы по-разному структурировать свои представления, чтобы упростить это. - person machineghost; 21.12.2012
comment
Например, если у вас есть представления A, B и C, которые используют модель X, но вы строите A, B и C в совершенно разных местах кода (что затрудняет совместное использование X между ними), я бы посмотрите, почему A, B и C строятся в таких разных местах. Если они должны быть, я бы посмотрел, все ли эти пятна имеют общий связанный объект (и затем, возможно, поместил бы X на этот объект). И если нет никакой связи ни в размещении кода, ни в общих переменных между A, B и C, тогда я должен спросить, действительно ли я вообще разделяю модель между ними? - person machineghost; 21.12.2012
comment
Хорошо, понял, это имеет большой смысл и отвечает на мой вопрос. Единственное, что я бы поспорил с этим сценарием, это то, что он делает взгляды довольно связанными с тем, на что он похож. Вы должны получить модель из какого-то места (или мест) во всех местах, где вы создаете другой экземпляр A, B, C. Backbone-relational сделал это прекрасно, переопределив все операции синхронизации, так что это невозможно для идентичные модели (модели с одинаковым идентификатором) для создания. Если вам интересно увидеть мою точную ситуацию, вот она i.imgur.com/kAUD1.jpg< /а>. - person JayD3e; 21.12.2012
comment
@ JayD3e - Связь во многом зависит от вашей общей архитектуры. Я не знаю о machineghost, но когда я в последний раз делал магистральное приложение, я следовал правилу представления, которое заботится только о себе и создании своих дочерних элементов. Часть создания дочерних элементов включает в себя передачу модели или коллекции для использования. В любом случае дочерние представления зависят от родительского представления, точно так же, как <li> зависит от существования <ul> или <ol>, так что на самом деле не так уж много дополнительной связи при передаче параметра. - person Shauna; 21.12.2012
comment
@machineghost, может быть, измените свой ответ на более похожий на то, что вы упомянули ранее? И я отмечу это как лучший ответ. - person JayD3e; 21.12.2012
comment
Я его отредактировал... окончательный вариант вышел немного длинноват, но, надеюсь, будет полезен будущим читателям. - person machineghost; 21.12.2012