Я только начинаю с angularjs и работаю над преобразованием нескольких старых плагинов JQuery в директивы Angular. Я бы хотел определить набор параметров по умолчанию для моей директивы (element), который можно переопределить, указав значение параметра в атрибуте.
Я оглянулся на то, как это сделали другие, и в библиотеке angular-ui, похоже, ui.bootstrap.pagination делает нечто подобное.
Сначала все параметры по умолчанию определяются в постоянном объекте:
.constant('paginationConfig', {
itemsPerPage: 10,
boundaryLinks: false,
...
})
Затем getAttributeValue
к контроллеру директивы присоединяется служебная функция:
this.getAttributeValue = function(attribute, defaultValue, interpolate) {
return (angular.isDefined(attribute) ?
(interpolate ? $interpolate(attribute)($scope.$parent) :
$scope.$parent.$eval(attribute)) : defaultValue);
};
Наконец, это используется в функции связывания для чтения в атрибутах как
.directive('pagination', ['$parse', 'paginationConfig', function($parse, config) {
...
controller: 'PaginationController',
link: function(scope, element, attrs, paginationCtrl) {
var boundaryLinks = paginationCtrl.getAttributeValue(attrs.boundaryLinks, config.boundaryLinks);
var firstText = paginationCtrl.getAttributeValue(attrs.firstText, config.firstText, true);
...
}
});
Это выглядит довольно сложной настройкой для чего-то стандартного, например, для замены набора значений по умолчанию. Есть ли другие способы сделать это, которые распространены? Или это нормально - всегда определять такие служебные функции, как getAttributeValue
и параметры синтаксического анализа? Мне интересно узнать, какие у людей разные стратегии для решения этой общей задачи.
Также в качестве бонуса мне не понятно, зачем interpolate
нужен этот параметр.
источник
ui.bootstrap.pagination
все сложнее? Думал, что если использовать функцию компиляции, любые изменения атрибутов, сделанные позже, не будут отражены, но это не похоже на правду, так как на этом этапе устанавливаются только значения по умолчанию. Думаю, здесь должен быть какой-то компромисс.compile
вы не можете прочитать атрибуты, которые должны быть интерполированы, чтобы получить значение (которое содержит выражение). Но если вы хотите проверить только, если атрибут пуст - он будет работать без каких-либо компромиссов для вас (перед атрибутом интерполяции будет содержаться строка с выражением).ui.bootstrap.pagination
примере, я нашел этот очень полезный пример: jsfiddle.net/EGfgHlink
опция, вы все равно можете вернуть функцию в вашcompile
вариант. документ здесьattributes.foo = '["one", "two", "three"]'
вместоattributes.foo = ["one", "two", "three"]
Используйте
=?
флаг для свойства в блоке области действия директивы.источник
=?
доступен с 1.1.xtrue
или вfalse
качестве значений, вы бы (я думаю) захотели использовать, например,$scope.hasName = angular.isDefined($scope.hasName) ? $scope.hasName : false;
вместо этого.=?
, но не с односторонним связыванием@?
.link
функции? Исходя из моего понимания, назначение во времяlink
должно избегать$scope.$apply()
цикла, не так ли?Я использую AngularJS v1.5.10 и нашел
preLink
функция компиляции довольно хорошо работает для установки значений атрибутов по умолчанию.Просто напоминание:
attrs
держит сырье значения атрибута DOM, которые всегда являются либоundefined
строками, либоscope
содержит (среди прочего) значения атрибута DOM, проанализированные в соответствии с предоставленной спецификацией изолированной области (=
/<
/@
/ и т. д.).Сокращенный фрагмент:
источник