web-dev-qa-db-fra.com

Comment lier des valeurs booléennes dans les directives angular?

Je voudrais lier/définir des attributs booléens à une directive. Mais je ne sais vraiment pas comment faire cela et atteindre le comportement suivant.

Imaginez que je veuille mettre un drapeau sur une structure, disons qu'une liste est pliable ou non. J'ai le code HTML suivant:

<list items="list.items" name="My list" collapsable="true"></list>

items sont liés dans les deux sens, name n'est qu'un attribut

J'aimerais que cet attribut collapsable soit disponible dans la portée $ de la liste soit en passant une valeur (true, false ou autre), soit une liaison bidirectionnelle

<list items="list.items" name="{{list.name}}" collapsable="list.collapsed"></list>

Je suis en train de développer certains composants de l'interface utilisateur et je voudrais fournir plusieurs façons d'interagir avec eux. Peut-être qu'avec le temps, certains gars aimeraient connaître l'état de ce composant, qu'il soit réduit ou non, en passant la propriété d'un objet à l'attribut.

Existe-t-il un moyen d'y parvenir? Veuillez me corriger si j'ai mal compris quelque chose ou si je me trompe.

Merci

30
Chris X

Vous pouvez configurer votre propre comportement de liaison de données unidirectionnelle pour les booléens comme ceci:

link: function(scope, element, attrs) {

    attrs.$observe('collapsable', function() {

        scope.collapsable = scope.$eval(attrs.collabsable);
    });

}

L'utilisation de $ observe ici signifie que votre "surveillance" n'est affectée que par la modification de l'attribut et ne sera pas affectée si vous modifiez directement le $ scope.collapsable à l'intérieur de votre directive.

26
bingles

Créez un champ d'application sur la directive qui établit une liaison bidirectionnelle:

app.controller('ctrl', function($scope)
{
    $scope.list = {
        name: 'Test',
        collapsed: true,
        items: [1, 2, 3]
    };
});

app.directive('list', function()
{
    return {
        restrict: 'E',
        scope: {
            collapsed: '=',
            name: '=',
            items: '='
        },
        template:
            '<div>' +
                '{{name}} collapsed: {{collapsed}}' +
                '<div ng-show="!collapsed">' +
                    '<div ng-repeat="item in items">Item {{item}}</div>' +
                '</div>' +
                '<br><input type="button" ng-click="collapsed = !collapsed" value="Inside Toggle">' +
            '</div>'
    };
});

Passez ensuite les options en tant qu'attributs:

<list items="list.items" name="list.name" collapsed="list.collapsed"></list>

http://jsfiddle.net/aaGhd/3/

8
noj

Vous ne pouvez pas passer des chaînes true ou false comme valeur d'attribut et prendre également en charge le passage d'une propriété d'étendue telle que list.collapsed comme valeur d'attribut pour la liaison bidirectionnelle. Vous devez choisir d'une manière ou d'une autre.

En effet, vous ne pouvez spécifier qu'une seule façon d'interpréter la valeur de l'attribut dans votre directive lorsque vous utilisez une étendue isolée.

Je suppose que vous pourriez utiliser = dans votre diretive, et vérifiez également votre fonction de liaison si attrs.collapsable est défini sur true ou false: si c'est le cas, vous savez qu'une valeur booléenne a été transmise et, dans le cas contraire, utilisez la liaison de données bidirectionnelle. Mais c'est hacky.

5
Mark Rajcok

Je sais que j'ai un an de retard à ce sujet, mais vous pouvez réellement le faire en utilisant la fonction de lien ( https://docs.angularjs.org/guide/directive ). La signature ressemble à ceci:

function link(scope, element, attrs) { ... } 

Cet objet attrs sera rempli avec les valeurs brutes transmises. Vous pouvez donc dire si (attrs.collapsed == 'true') {...} ou quelque chose du genre.

2
Brandon Prudent

Étant donné que Angular 1,3 attrs. $ Observe semble également se déclencher pour les attributs non définis, donc si vous voulez prendre en compte un attribut non défini, vous devez faire quelque chose comme:

link: function(scope, element, attrs) {
    attrs.$observe('collapsable', function() {
      scope.collapsable = scope.$eval(attrs.collapsable);
      if (scope.collapsable === undefined) {
        delete scope.collapsable;
      }
    });
  },
2
user1338062