web-dev-qa-db-fra.com

Comment utiliser "ng-repeat" dans le modèle d'une directive dans Angular JS?

Je suis nouveau dans Angular JS et j'essaie de créer une directive personnalisée qui sera utilisée comme suit:

<div linkedlist listcolumns="{{cashAccountsColumns}}"></div>

Corrps. contrôleur sera:

$scope.cashAccountsColumns = [
  {"field": "description", "title": "Description"},
  {"field": "owner", "title":"Owner"},
  {"field": "currentBalance", "title":"Current Balance" }
];

Et le code directive est:

return {
      restrict : 'EA',
      transclude : false,
      templateUrl : 'html/linkedlist.html',
      scope: {
         listcolumns: "@"
      },
      link : function(scope, element, attrs) {
      }
}

template est:

<table class="box-table" width="100%">
  <thead>
    <tr>
      <th scope="col" ng-repeat="column in listcolumns">
        {{column.title}}
      </th>
    </tr>
  </thead>
</table>

Mais ça ne fonctionne pas. Je ne reçois pas la valeur de column.title à l'écran, mais trop de lignes, comme ci-dessous, ajoutées à DOM:

<th ng-repeat="column in listcolumns" scope="col" class="ng-scope ng-binding"></th>
50
user2401127

Passer un objet entier avec attribut ne fonctionnera pas, vous devez utiliser une liaison à double sens. Changez simplement la liaison de @ à = et modifiez le code HTML ci-dessous pour que cela fonctionne

modifications apportées à code de la directive :

// ...
scope: {
    listcolumns: "="
},
// ...

modifications apportées à template :

  <div linkedlist listcolumns="cashAccountsColumns"></div>
96
Ajay Beniwal

La réponse de @ AjayBeniwal est correcte, mais je pense qu'elle pourrait utiliser des explications supplémentaires. 

Comme l'indique la Documentation angulaire (dans la section "Isolation du champ d'application d'une directive"), l'option scope est un objet contenant une propriété pour chaque liaison de portée d'isolat. Nous l'utilisons pour séparer (isoler) la portée d'une directive de la portée de l'extérieur, puis mapper la portée externe à la portée interne de la directive.

Le nom de chaque propriété de l'objet scope correspond à la propriété directives isolate scope. Dans l'exemple de la question, la seule propriété de l'objet scope est listcolumns. Pour cette raison, il doit également y avoir un attribut correspondant sur le code HTML créant la directive:

<div linkedlist listcolumns="cashAccountsColumns"></div>

Le nom de la propriété scope et l'attribut de la directive ne doivent cependant pas avoir le même nom. Nous pouvons mapper ces deux valeurs comme ceci:

<div linkedlist short-name="cashAccountsColumns"></div>

-

controller: function ($scope) {
    $scope.cashAccountsColumns = 'value';
},
scope: {
     moreDescriptiveName: "=shortName"
},

Dans les cas où le nom de l'attribut est identique à la valeur que vous souhaitez lier à l'intérieur de la portée de la directive, vous pouvez utiliser cette syntaxe abrégée:

<div linkedlist my-name="cashAccountsColumns"></div>

-

controller: function ($scope) {
    $scope.cashAccountsColumns = 'value';
},
scope: {
     myName: "="
},


De plus, dans cet exemple, la valeur de l'attribut de la directive doit correspondre à une propriété de la portée externe de la directive. En effet, = dans =shortName utilise la liaison bidirectionnelle des attributs de la portée externe à la portée isolate, forçant ainsi la valeur de l'attribut de la directive à être évaluée en tant qu'expression. Comme cette réponse fait remarquer avec éloquence, si nous voulons plutôt passer une chaîne littérale, nous pouvons soit utiliser @ à la place de =, soit entourer la propriété isolate de la directive avec des guillemets simples et doubles:

scope: {
     moreDescriptiveName: "@"
},

OR

<div linkedlist short-name="'cashAccountsColumns'"></div>
0
Zach Posten