Часть 1
- Как писать директивы?
- Простой вариант создания директивы
- Развернутый вариант
- Link и Compile
Template и TemplateUrl
Продолжая разговор о директивах, надо отметить, что директивы по сути являются модулями, если абстрагироваться от терминологии Angularjs. То есть, в идеале, они должны быть самостоятельным элементом интерфейса со своими функционалом и разметкой. Разметка при этом может задаваться напрямую в параметре Template или храниться в отдельном файле, URL которого указывается в TemplateUrl:
[jsFiddle]
angular.module('helloHabrahabr', []) .directive('habraHabr', function() { return { template:"<span>Hello Habr!</span>" /* или */ templateUrl:"helloHabr.html" } });
helloHabr.html
<span>Hello Habr!</span>
При этом в случае, если шаблон подгружается, функции Compile и Link выполняются после загрузки.
Scope
Параметр Scope определяет область видимости внутри директивы. Возможно несколько вариантов:
Не указывать scope вовсе. Тогда директива, грубо говоря, работает напрямую в области видимости контроллера. То есть все переменные контроллера равны переменным директивы.
[jsFiddle]
<div ng-app="helloHabrahabr"> <div ng-controller="forExampleController"> {{hello}} <span habra-habr></span> </div> </div>
function forExampleController($scope){ $scope.hello="Hello Habr!"; } angular.module('helloHabrahabr', []) .directive('habraHabr', function() { return { template:"<input ng-model='hello'>{{hello}}" } });
Другой вариант. Scope = true. В этом случае, scope будет наследоваться. То есть поля, заданные в родительском scope будут отображаться и в scope директивы, но при этом все изменения будут локальны:
[jsFiddle]
function forExampleController($scope){ $scope.hello="Hello Habr!"; } angular.module('helloHabrahabr', []) .directive('habraHabr', function() { return { template:"<input ng-model='hello'>{{hello}}", scope:true } });
И наконец, самый интересный вариант. Задать изолированный scope. То есть scope, который по умолчанию абсолютно независим от контекста вызова директивы. Для этого нужно просто указать в качестве scope пустой объект {}:
[jsFiddle]
angular.module('helloHabrahabr', []) .directive('habraHabr', function() { return { template:"<input ng-model='hello'>{{hello}}", scope:{ } } });
Дальше есть несколько вариантов работы с таким изолированным scope. Но все они сводятся к одному принципу. В объекте, который мы объявили для scope, в качестве имени свойства слева указывается некая переменная директивы, а справа название атрибута DOM c одним из трех символов в начале: @/=/&. То есть вот так:
scope:{ localVar1:"@attrName1", localVar2:"=attrName2", localVar3:"&attrName3" }
Либо еще одни вариант. Не указывать имя атрибута, тогда оно будет равно имени переменной:
scope:{ localVar1:"@", /*localVar1:"@localVar1" */ localVar2:"=", /*localVar2:"@localVar2" */ localVar3:"&" /*localVar3:"@localVar3" */ }
Теперь по порядку. Префикс "@" означает, что локальной переменной будет присвоено значение атрибута:
[jsFiddle]
<div ng-app="helloHabrahabr"> <span habra-habr="hello" some-attr="Hello Habr!"></span> </div>
angular.module('helloHabrahabr', []) .directive('habraHabr', function() { return { template:"{{hello}}", scope:{ hello:'@someAttr' } } });
Префикс "=" означает, что в атрибуте передается уже не строчка, а имя некоторой переменной в текущем Scope. И локальная переменная будет напрямую с ней связана. То есть изменения переменной как внутри директивы, так и вне отразятся и там, и там:
[jsFiddle]
<div ng-app="helloHabrahabr"> <div ng-controller="forExampleController"> {{hello}} <span habra-habr some-attr="hello"></span> </div> </div>
function forExampleController($scope){ $scope.hello="Hello Habr!"; } angular.module('helloHabrahabr', []) .directive('habraHabr', function() { return { template:"<input ng-model='hello'>{{hello}}", scope:{ hello:'=someAttr' } } });
И наконец, последний вариант "&" предполагает, что атрибут содержит некое выражение. К примеру, «c= a+b» или проще «a+b». И теперь ваша локальная переменная становится функцией, в которую можно передавать параметры. Параметры передаются в объекте, ключами которого выступают имена переменных в функции. В конкретном случае, localVar({a:1,b:2}) вернет три.
[jsFiddle]
angular.module('helloHabrahabr', []) .directive('habraHabr', function() { return { template:"{{helloFn({a:1,b:2})}}", scope:{ helloFn:'&someAttr' } } });
При этом интересно, что по умолчанию, если не передавать в локальную функцию никаких параметров, переменным будут присвоены значения соответствующих переменных в родительском scope. А если указать переменную -результат, то и она также будет доступна из вне:
[jsFiddle]
<div ng-app="helloHabrahabr"> <div ng-controller="forExampleController"> a={{a}} b={{b}} parent's hello={{hello}} <span habra-habr some-attr="hello= a+b"></span> </div> </div>
function forExampleController($scope){ $scope.a="Hello"; $scope.b=" Habr!"; } angular.module('helloHabrahabr', []) .directive('habraHabr', function() { return { template:"default helloFn={{helloFn()}}\ custom hello={{helloFn({a:'Bye',b:'Habr'})}}", scope:{ helloFn:'&someAttr' } } });
Всем спасибо, продолжение следует.
ссылка на оригинал статьи http://habrahabr.ru/post/180365/
Добавить комментарий