Какой замечательный вопрос! Я люблю , чтобы услышать то , что говорят другие, но вот принципы , которые я использую.
Высотная предпосылка: scope используется как «клей», который мы используем для связи между родительским контроллером, директивой и шаблоном директивы.
Родительская Область: scope: false
так что никакой новой области вообще нет
Я использую это не очень часто, но, как сказал @MarkRajcok, если директива не обращается к каким-либо переменным области видимости (и, очевидно, не устанавливает их!), То, на мой взгляд, это нормально. Это также полезно для дочерних директив, которые используются только в контексте родительской директивы (хотя из этого всегда есть исключения) и у которых нет шаблона. По сути, все, что связано с шаблоном, не имеет общей области видимости, потому что вы по своей сути выставляете эту область для доступа и манипулирования (но я уверен, что есть исключения из этого правила).
В качестве примера я недавно создал директиву, которая рисует (статическую) векторную графику с использованием библиотеки SVG, которую я нахожусь в процессе написания. Он имеет $observe
два атрибута ( width
и height
) и использует их в своих вычислениях, но не устанавливает и не читает никаких переменных области и не имеет шаблона. Это хороший вариант использования, чтобы не создавать другую область; нам не нужен, так зачем?
Но в другой директиве SVG мне потребовался набор данных, который нужно было использовать, и, кроме того, я должен был хранить крошечную информацию о состоянии. В этом случае использование родительской области было бы безответственным (опять же, вообще говоря). Так что вместо ...
Детская сфера: scope: true
Директивы с дочерней областью являются контекстно-зависимыми и предназначены для взаимодействия с текущей областью.
Очевидно, что ключевым преимуществом этого по сравнению с изолированной областью является то, что пользователь может свободно использовать интерполяцию для любых атрибутов, которые они хотят; Например, использование class="item-type-{{item.type}}"
директивы с изолированной областью не будет работать по умолчанию, но прекрасно работает с директивой с дочерней областью, потому что все, что интерполируется, все еще может быть найдено по умолчанию в родительской области. Кроме того, сама директива может безопасно оценивать атрибуты и выражения в контексте своей собственной области, не беспокоясь о загрязнении или повреждении родительского объекта.
Например, всплывающая подсказка - это то, что просто добавляется; Изолированная область не будет работать (по умолчанию, см. ниже), потому что ожидается, что здесь мы будем использовать другие директивы или интерполированные атрибуты. Подсказка - это просто улучшение. Но подсказка также должна установить некоторые вещи в области видимости, которые будут использоваться с под-директивой и / или шаблоном, и, очевидно, управлять своим собственным состоянием, так что было бы очень плохо использовать родительскую область видимости. Мы либо загрязняем его, либо повреждаем, и ни один не является буэно.
Я чаще использую детские прицелы, чем одиночные или родительские.
Изолировать область: scope: {}
Это для многоразовых компонентов. :-)
А если серьезно, я думаю о «повторно используемых компонентах» как о «автономных компонентах». Намерение состоит в том, что они должны использоваться для определенной цели, поэтому объединение их с другими директивами или добавление других интерполированных атрибутов к узлу DOM по своей сути не имеет смысла.
Чтобы быть более конкретным, все, что необходимо для этой автономной функциональности, предоставляется через определенные атрибуты, оцениваемые в контексте родительской области; это либо односторонние строки ('@'), либо односторонние выражения ('&'), либо двусторонние привязки переменных ('=').
На автономных компонентах не имеет смысла применять другие директивы или атрибуты к нему, потому что он существует сам по себе. Его стиль регулируется собственным шаблоном (при необходимости) и может включать соответствующий контент (при необходимости). Он автономен, поэтому мы помещаем его в изолированную область также, чтобы сказать: «Не связывайтесь с этим. Я даю вам определенный API через эти несколько атрибутов».
Хорошей практикой является исключение как можно большего количества материалов на основе шаблонов из ссылки директивы и функций контроллера. Это обеспечивает другую «API-подобную» конфигурационную точку: пользователь директивы может просто заменить шаблон! Все функциональные возможности остались прежними, и его внутренний API никогда не затрагивался, но мы можем связываться со стилем и реализацией DOM столько, сколько нам нужно. UI / bootstrap - отличный пример того, как сделать это хорошо, потому что Peter & Pawel потрясающие.
Области применения изолята также отлично подходят для использования с включением. Взять вкладки; они представляют собой не только всю функциональность, но все, что находится внутри, может свободно оцениваться из родительской области, оставляя вкладки (и панели), чтобы делать все, что они хотят. Вкладки явно имеют свое собственное состояние , которое принадлежит области (для взаимодействия с шаблоном), но это состояние не имеет ничего общего с контекстом, в котором оно использовалось - оно полностью внутреннее того, что делает директиву tab директивой tab. Кроме того, нет смысла использовать какие-либо другие директивы с вкладками. Это вкладки - и мы уже получили эту функциональность!
Окружите его большей функциональностью или включите больше функциональности, но эта директива уже есть.
Из всего сказанного следует отметить, что существуют некоторые способы обойти некоторые ограничения (то есть функции) изолированной области видимости, как намекал @ProLoser в своем ответе. Например, в разделе дочерней области я упомянул интерполяцию при разрыве ненаправленных атрибутов при использовании изолированной области (по умолчанию). Но пользователь может, например, просто использовать, class="item-type-{{$parent.item.type}}"
и это будет снова работать. Поэтому, если есть веская причина для использования изолированной области над дочерней областью, но вы беспокоитесь о некоторых из этих ограничений, знайте, что при необходимости вы можете обойти практически все из них.
Резюме
Директивы без новой области видимости доступны только для чтения; им полностью доверяют (то есть, они встроены в приложение) и они не касаются гнезда. Директивы с дочерней областью добавляют функциональность, но они не единственные . Наконец, отдельные области предназначены для директив, которые являются всей целью; они автономны, так что все в порядке (и большинство «правильных»), позволяя им стать мошенниками.
Я хотел высказать свои первоначальные мысли, но, как я думаю о других вещах, я буду обновлять это. Но святое дерьмо - это долго для ТАКОГО ответа ...
PS: Абсолютно тангенциальный, но так как мы говорим о сферах, я предпочитаю говорить «прототип», тогда как другие предпочитают «прототип», который кажется более точным, но просто скатывается с языка совсем не хорошо. :-)