Je commence tout juste avec angularjs et je travaille à la conversion de quelques anciens plugins JQuery en directives Angular. J'aimerais définir un ensemble d'options par défaut pour ma directive (élément), qui peut être remplacé en spécifiant la valeur de l'option dans un attribut.
J'ai jeté un œil autour de la façon dont d'autres l'ont fait, et dans la bibliothèque angular-ui , la i.bootstrap.pagination semble faire quelque chose de similaire.
Toutes les options par défaut sont d'abord définies dans un objet constant:
.constant('paginationConfig', {
itemsPerPage: 10,
boundaryLinks: false,
...
})
Ensuite, une fonction utilitaire getAttributeValue
est associée au contrôleur de directive:
this.getAttributeValue = function(attribute, defaultValue, interpolate) {
return (angular.isDefined(attribute) ?
(interpolate ? $interpolate(attribute)($scope.$parent) :
$scope.$parent.$eval(attribute)) : defaultValue);
};
Enfin, cela est utilisé dans la fonction de liaison pour lire les attributs en tant que
.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);
...
}
});
Cela semble être une configuration plutôt compliquée pour quelque chose d'aussi standard que vouloir remplacer un ensemble de valeurs par défaut. Y a-t-il d'autres moyens de faire cela qui sont courants? Ou est-il normal de toujours définir une fonction utilitaire telle que getAttributeValue
et d'analyser les options de cette manière? Je suis intéressé à savoir quelles sont les différentes stratégies que les gens ont pour cette tâche commune.
De plus, en prime, je ne comprends pas pourquoi le paramètre interpolate
est requis.
Vous pouvez utiliser compile
fonction - lire les attributs s’ils ne sont pas définis - les renseigner avec les valeurs par défaut.
.directive('pagination', ['$parse', 'paginationConfig', function($parse, config) {
...
controller: 'PaginationController',
compile: function(element, attrs){
if (!attrs.attrOne) { attrs.attrOne = 'default value'; }
if (!attrs.attrTwo) { attrs.attrTwo = 42; }
},
...
}
});
Utilisez l'indicateur =?
pour la propriété dans le bloc scope de la directive.
angular.module('myApp',[])
.directive('myDirective', function(){
return {
template: 'hello {{name}}',
scope: {
// use the =? to denote the property as optional
name: '=?'
},
controller: function($scope){
// check if it was defined. If not - set a default
$scope.name = angular.isDefined($scope.name) ? $scope.name : 'default name';
}
}
});
J'utilise AngularJS v1.5.10 et j'ai trouvé que preLink
fonction de compilation fonctionnait plutôt bien pour la définition des valeurs d'attribut par défaut.
Juste un rappel:
attrs
contient les valeurs d'attribut DOM brutes brutes qui sont toujours undefined
ou des chaînes.scope
contient (entre autres) les valeurs d'attribut DOM analysées en fonction de la spécification de portée d'isolat fournie (=
/<
/@
/etc.).Extrait abrégé:
.directive('myCustomToggle', function () {
return {
restrict: 'E',
replace: true,
require: 'ngModel',
transclude: true,
scope: {
ngModel: '=',
ngModelOptions: '<?',
ngTrueValue: '<?',
ngFalseValue: '<?',
},
link: {
pre: function preLink(scope, element, attrs, ctrl) {
// defaults for optional attributes
scope.ngTrueValue = attrs.ngTrueValue !== undefined
? scope.ngTrueValue
: true;
scope.ngFalseValue = attrs.ngFalseValue !== undefined
? scope.ngFalseValue
: false;
scope.ngModelOptions = attrs.ngModelOptions !== undefined
? scope.ngModelOptions
: {};
},
post: function postLink(scope, element, attrs, ctrl) {
...
function updateModel(disable) {
// flip model value
var newValue = disable
? scope.ngFalseValue
: scope.ngTrueValue;
// assign it to the view
ctrl.$setViewValue(newValue);
ctrl.$render();
}
...
},
template: ...
}
});