Как использовать ng-show в директиве с изолированной областью
У меня есть директива, которую я использую следующим образом:
<dir model="data"></dir>
Директива имеет изолированную область действия.
scope :{
model:'='
}
Теперь я пытаюсь использовать ng-show
в этой директиве, используя другой атрибут моей области $scope, например:
<dir ng-show="show" model="data"></dir>
Но он не работает, потому что директива пытается найти атрибут show
в своей области.
Я не хочу, чтобы директива знала о том, что его контейнер может захотеть скрыть его.
Обходной путь, который я нашел, - это обернуть директиву в <div>
и применить ng-show
к этому элементу, но мне не нравится дополнительный элемент, который заставляет меня использовать:
<div ng-show="show" >
<dir model="data"></dir>
</div>
Есть ли лучший способ сделать это?
Смотрите этот плункер: http://plnkr.co/edit/Q3MkWfl5mHssUeh3zXiR?p=preview
Ответы
Ответ 1
Вы можете рассмотреть возможность перехода на Angular 1.2 или выше. Область изоляции теперь доступна только для директив с свойством scope. Это означает, что ng-show больше не зависит от вашей директивы, и вы можете написать ее точно так же, как вы пытались сделать это в первую очередь:
<dir ng-show="show" model="data"></dir>
@Angular -Developers: Отличная работа, ребята!
Ответ 2
Обновление:. Этот ответ относится к выпускам Angular до 1.2. См. Ответ @lex82 для Angular 1.2.
Поскольку ваша директива dir
создает область выделения, все директивы, определенные в одном и том же элементе (dir
в этом случае), будут использовать эту область выделения. Вот почему ng-show
ищет свойство show
в области изоляции, а не в родительской области.
Если ваша директива dir
действительно является автономным/автономным/повторно используемым компонентом , и поэтому она должна использовать область изоляции, ваше упаковочное решение, вероятно, лучше всего (лучше, чем использование $parent
, IMO), потому что такие директивы обычно не должны использоваться с другими директивами одного и того же элемента (или вы получаете именно такую проблему).
Если вашей директиве не нужна область выделения, ваша проблема исчезнет.
Ответ 3
Добавление следующей функции ссылки решает проблему. Это дополнительный шаг для создателя компонента, но делает компонент более интуитивным.
function link($scope, $element, attr, ctrl) {
if (attr.hasOwnProperty("ngShow")) {
function ngShow() {
if ($scope.ngShow === true) {
$element.show();
}
else if($scope.ngShow === false) {
$element.hide();
}
}
$scope.$watch("ngShow", ngShow);
setTimeout(ngShow, 0);
}
//... more in the link function
}
Вам также понадобится настроить привязки областей для ngShow
scope: {
ngShow: "="
}
Ответ 4
Просто используйте $parent
для родительской области следующим образом:
<dir ng-show="$parent.show" model="data"></dir>
Отказ
Я думаю, что это точный ответ на ваш вопрос, но я признаю, что он не идеален с эстетической точки зрения. Однако обернуть <div>
тоже не очень приятно. Я думаю, что это можно оправдать, потому что из другого параметра, переданного в область изоляции, можно видеть, что в директиве фактически есть область выделения. С другой стороны, я должен признать, что я регулярно забываю $parent в первую очередь, а затем задаюсь вопросом, почему он не работает.
Конечно, было бы яснее добавить дополнительный атрибут is-visible="expression"
и вставить ng-show
внутренне. Но вы заявили в своем вопросе, что пытались избежать этого решения.
Обновление: Не работает в Angular 1.2 или выше.