363 votes

Comment obtenir des attributs évalués à l’intérieur d’une directive custom

J’essaie d’obtenir un attribut évalué de ma directive custom, mais je ne peux pas trouver la bonne façon de le faire.

J’ai créé ce jsFiddle d’élaborer.

Ce qui me manque ?

571voto

Umur Kontacı Points 12524

Avis: je ne mise à jour de cette réponse que j'ai trouver de meilleures solutions. J'ai aussi garder l'ancienne réponses de référence pour l'avenir, tant qu'ils sont liés. Plus récente et la meilleure réponse vient en premier.

Meilleure réponse:

Directives angularjs sont très puissants, mais il faut du temps pour comprendre ce que ce processus se cachent derrière eux.

Lors de la création de directives, angularjs permet de créer un isolé portée avec certaines liaisons à la portée parent. Ces liaisons sont spécifiées par l' attribut vous attachez de l'élément dans le DOM et la façon de définir le champ d'application de la propriété dans la directive définition de l'objet.

Il y a 3 types de liaison des options que vous pouvez définir dans le champ d'application et de vous écrire ces comme des préfixes attribut associé.

angular.module("myApp", []).directive("myDirective", function () {
    return {
        restrict: "A",
        scope: {
            text: "@myText",
            twoWayBind: "=myTwoWayBind",
            oneWayBind: "&myOneWayBind"
        }
    };
}).controller("myController", function ($scope) {
    $scope.foo = {name: "Umur"};
    $scope.bar = "qwe";
});

HTML

<div ng-controller="myController">
    <div my-directive my-text="hello {{ bar }}" my-two-way-bind="foo" my-one-way-bind="bar">
    </div>
</div>

Dans ce cas, dans le champ d'application de la directive (si c'est en fonction de liaison ou contrôleur), nous pouvons accéder à ces propriétés comme ceci:

/* Directive scope */

in: $scope.text
out: "hello qwe"
// this would automatically update the changes of value in digest
// this is always string as dom attributes values are always strings

in: $scope.twoWayBind
out: {name:"Umur"}
// this would automatically update the changes of value in digest
// changes in this will be reflected in parent scope

// in directive's scope
in: $scope.twoWayBind.name = "John"

//in parent scope
in: $scope.foo.name
out: "John"


in: $scope.oneWayBind() // notice the function call, this binding is read only
out: "qwe"
// any changes here will not reflect in parent, as this only a getter .

"Toujours OK" Réponse:

Depuis cette réponse a été accepté, mais a des problèmes, je vais mettre à jour cette pour une meilleure. Apparemment, $parse est un service qui ne se trouve pas dans les propriétés de la portée actuelle, ce qui signifie qu'il ne prend angulaire des expressions et n'atteignent pas à la portée. {{,}} expressions sont collectées alors que angularjs initier ce qui signifie que lorsque nous essayons d'accéder à nos directives de l' postlink méthode, ils sont déjà compilées. ({{1+1}} est 2 dans la directive déjà).

C'est de cette façon que vous souhaitez utiliser:

var myApp = angular.module('myApp',[]);

myApp.directive('myDirective', function ($parse) {
    return function (scope, element, attr) {
        element.val("value=" + $parse(attr.myDirective)(scope));
    };
});

function MyCtrl($scope) {
    $scope.aaa = 3432;
}​

.

<div ng-controller="MyCtrl">
    <input my-directive="123">
    <input my-directive="1+1">
    <input my-directive="'1+1'">
    <input my-directive="aaa">
</div>​​​​​​​​

Une chose que vous devriez remarquer ici est que, si vous souhaitez définir la valeur de chaîne, vous devez envelopper dans des guillemets. (Voir le 3ème entrée)

Voici le violon pour jouer avec: http://jsfiddle.net/neuTA/6/

Vieille Réponse:

Je ne suis pas la suppression de ce pour les gens qui peuvent être induits en erreur, comme moi, de noter que l'utilisation d' $eval est parfaitement bien la bonne façon de le faire, mais $parse a un comportement différent, vous n'aurez probablement pas besoin d'utiliser dans la plupart des cas.

La façon de le faire est, une fois de plus, à l'aide de scope.$eval. Non seulement il compile l'angle de l'expression, il a également accès à l'étendue actuelle des propriétés.

var myApp = angular.module('myApp',[]);

myApp.directive('myDirective', function () {
    return function (scope, element, attr) {
        element.val("value = "+ scope.$eval(attr.value));
    }
});

function MyCtrl($scope) {

}​

Ce qui vous manque est $eval.

http://docs.angularjs.org/api/ng.$rootScope.Champ#$eval

Exécute l'expression sur la portée actuelle de retourner le résultat. Toutes les exceptions dans l'expression sont propagées (non interceptée). Ceci est utile lors de l'évaluation angulaire expressions.

83voto

Mark Rajcok Points 85912

Pour une valeur d'attribut doit être interpolés sur une directive qui n'est pas en utilisant un cas isolé champ d'application, par exemple,

<input my-directive value="{{1+1}}">

l'utilisation des Attributs de la méthode des" $observe:

myApp.directive('myDirective', function () {
  return function (scope, element, attr) {
    attr.$observe('value', function(actual_value) {
      element.val("value = "+ actual_value);
    })
 }
});

De la directive de page,

l'observation interpolées attributs: Utiliser $observe d'observer les changements de valeur des attributs qui contiennent de l'interpolation (par exemple, src="{{bar}}"). Ce n'est pas seulement très efficace mais elle est aussi la seule façon d'obtenir facilement la valeur réelle, car lors de la liaison de la phase de l'interpolation n'a pas encore été évalué et donc la valeur est en ce moment à l' undefined.

Si la valeur de l'attribut est juste une constante, par exemple,

<input my-directive value="123">

vous pouvez utiliser $eval si la valeur est un nombre ou une valeur booléenne, et que vous voulez le type correct:

return function (scope, element, attr) {
   var number = scope.$eval(attr.value);
   console.log(number, number + 1);
});

Si la valeur de l'attribut est une chaîne de caractères constante, ou vous voulez que la valeur de type chaîne dans vos directives, vous pouvez y accéder directement:

return function (scope, element, attr) {
   var str = attr.value;
   console.log(str, str + " more");
});

Dans votre cas, cependant, puisque vous voulez soutenir les valeurs interpolées et constantes, utilisez $observe.

4voto

developersatish Points 99

Pour la même solution que je cherchais `` .
Voici le code qui résout le problème.

DOM HTML

Mon résultat est :

4voto

XMLilley Points 2351

Les autres réponses ici sont très corrects, et précieux. Mais parfois vous voulez juste simple: pour obtenir un bon vieux valeur analysée à la directive de l'instanciation, sans avoir besoin de mises à jour, et sans toucher à isoler la portée. Par exemple, il peut être utile de fournir un déclarative de la charge utile dans votre directive sous forme de tableau ou de hachage de l'objet sous la forme:

my-directive-name="['string1', 'string2']"

Dans ce cas, vous pouvez couper à la chasse et il suffit d'utiliser une belle base angular.$eval(attr.attrName).

element.val("value = "+angular.$eval(attr.value));

Travail De Violon.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X