Estou apenas começando com angularjs e estou trabalhando para converter alguns plugins JQuery antigos em diretivas Angular. Eu gostaria de definir um conjunto de opções padrão para minha diretiva (elemento), que pode ser substituída especificando o valor da opção em um atributo.
Examinei a maneira como os outros fizeram isso e, na biblioteca angular-ui , a página ui.bootstrap.pag parece fazer algo semelhante.
Primeiro, todas as opções padrão são definidas em um objeto constante:
.constant('paginationConfig', {
itemsPerPage: 10,
boundaryLinks: false,
...
})
Em seguida, uma getAttributeValue
função de utilitário é anexada ao controlador de diretiva:
this.getAttributeValue = function(attribute, defaultValue, interpolate) {
return (angular.isDefined(attribute) ?
(interpolate ? $interpolate(attribute)($scope.$parent) :
$scope.$parent.$eval(attribute)) : defaultValue);
};
Por fim, isso é usado na função de vinculação para ler atributos como
.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);
...
}
});
Parece uma configuração bastante complicada para algo tão padrão quanto querer substituir um conjunto de valores padrão. Existem outras maneiras comuns de fazer isso? Ou é normal sempre definir uma função de utilidade como getAttributeValue
e analisar opções dessa maneira? Estou interessado em descobrir quais estratégias diferentes as pessoas têm para essa tarefa comum.
Além disso, como bônus, não estou claro por que o interpolate
parâmetro é obrigatório.
fonte
ui.bootstrap.pagination
que as coisas são mais complicadas? Estava pensando que, se usando a função de compilação, qualquer alteração de atributo feita posteriormente não seria refletida, mas isso não parece ser verdade, pois apenas os padrões são definidos nesse estágio. Acho que deve haver alguma compensação sendo feita aqui.compile
não pode ler atributos, que devem ser interpolados para obter valor (que contém expressão). Mas se você quiser verificar apenas se o atributo está vazio - ele funcionará sem nenhuma troca por você (antes que o atributo de interpolação contenha sequência com expressão).ui.bootstrap.pagination
exemplo que eu encontrei este exemplo muito útil: jsfiddle.net/EGfgHlink
opção, ainda poderá retornar uma função em suacompile
opção. doc aquiattributes.foo = '["one", "two", "three"]'
, em vez deattributes.foo = ["one", "two", "three"]
Use o
=?
sinalizador para a propriedade no bloco de escopo da diretiva.fonte
=?
está disponível desde 1.1.xtrue
oufalse
como valores, você (eu acho) gostaria de usar, por exemplo$scope.hasName = angular.isDefined($scope.hasName) ? $scope.hasName : false;
.=?
, mas não com ligação unidirecional@?
.link
função? Com base no meu entendimento, atribuir durante olink
deve evitar um$scope.$apply()
ciclo, não deveria?Estou usando o AngularJS v1.5.10 e achei a
preLink
função de compilação funcionar muito bem para definir valores de atributo padrão.Apenas um lembrete:
attrs
mantém os valores brutos do atributo DOM que são sempre umaundefined
ou uma sequência de caracteres.scope
mantém (entre outras coisas) os valores do atributo DOM analisados de acordo com a especificação de escopo isolado fornecida (=
/<
/@
/ etc.).Snippet resumido:
fonte