2013-08-02 3 views
28

Ich möchte einige boolesche Attribute an eine Direktive binden/setzen. Aber ich weiß wirklich nicht, wie man das macht und das folgende Verhalten erreicht.Wie boolesche Werte in eckige Anweisungen zu binden?

Stellen Sie sich vor, dass ich eine Flagge auf eine Struktur setzen möchte, sagen wir, dass eine Liste kollabierbar ist oder nicht. Ich habe den folgenden HTML-Code:

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

items sind Zwei-Wege-binded ist name nur ein Attribut

Ich mag würde, dass collapsable Attribut in der Liste des $ Umfang zur Verfügung stehen, entweder indem Sie einen Wert vorbei (wahr, falsch oder was auch immer), wird entweder ein zwei-Wege-Bindung

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

ich habe einige UI-Komponenten zu entwickeln und ich mag mehrere Weg, um mit ihnen zu interagieren. Vielleicht möchten einige Leute mit der Zeit den Status dieser Komponente kennen, die entweder reduziert ist oder nicht, indem die Eigenschaft eines Objekts an das Attribut übergeben wird.

Gibt es einen Weg, dies zu erreichen? Bitte korrigieren Sie mich, wenn ich etwas falsch verstanden habe oder falsch liege.

Dank

+1

das Attribut als Einstellung Zwei-Wege binded mit ''='' funktioniert nicht, wenn direkte boolesche Werte 'true' oder' false' übergeben werden, weil ich den Wert des Bereichs nicht auf einen anderen Wert setzen kann. z.B. '$ scope.collapsable = false;' –

+0

werden Sie den Wert des kollabierbaren Attributs zur Laufzeit ändern oder zum Zeitpunkt der Auflösung gleich bleiben –

+0

Wenn sich die Werte nicht ändern, verwenden Sie einfach attrs ["collapsable"] –

Antwort

8

erstellen Umfang über die Richtlinie, die eine bidirektionale Bindung einrichtet:

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>' 
    }; 
}); 

dann die verschiedenen Optionen in als Attribute übergeben:

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

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

+2

Definitiv funktioniert das! Aber ich würde auch gerne in der Lage sein, das Attribut 'collapsed' mit einem booleschen Wert zu setzen, mit 'true' oder' false' –

+0

Für diejenigen, die sich über das obige wundern - 'collapsed =" true "' – AlexFoxGill

+0

collapsed = "true" arbeitet für diese Richtlinie. – hutingung

5

Sie können keine Zeichenfolgen true oder 012 übergebenals Attributwert und unterstützen auch die Übergabe einer Bereichseigenschaft wie list.collapsed als Attributwert für die Zweiwegebindung. Sie müssen auf die eine oder andere Weise auswählen.

Dies liegt daran, dass Sie bei der Verwendung eines isolate-Bereichs nur eine Möglichkeit angeben können, den Wert des Attributs in Ihrer Anweisung zu interpretieren.

Ich nehme an, Sie = in Ihrem diretive nutzen könnten, und auch in Ihrer Verknüpfungsfunktion überprüfen, ob attrs.collapsable auf true oder false eingestellt ist: Wenn ja, dann wissen Sie, ein boolean Wert übergeben wurde, und wenn nicht, verwenden Sie die Zwei- Weg Datenbindung. Aber das ist hacky.

2

Ich weiß, ich bin wie ein Jahr zu spät, aber Sie können dies tatsächlich tun, indem Sie die Link-Funktion (https://docs.angularjs.org/guide/directive) verwenden. Die Signatur sieht wie folgt aus:.

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

Das attrs Objekt wird mit den Rohwerten gebenen gefüllt werden, so könnte man sagen, wenn (attrs.collapsed == ‚true‘) {...} oder so .

+1

Das wird nicht funktionieren. Alle Werte in einem Attribut haben den Typ string. Wenn Sie also collapsed = "false" setzen, dann prüfen Sie, ob (attrs.collapsed), es wäre wahr, weil die Zeichenfolge "false" truthy ist –

+0

In der Tat. Ich habe das Beispiel mit einem einfachen "echten" Stringtest aktualisiert. Ich denke, dass es die Absicht der Frage adressiert. –

24

Sie können Ihre eigenen 1-Wege-Datenbindung Verhalten für booleans wie folgt konfiguriert werden:

link: function(scope, element, attrs) { 

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

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

} 

Verwendung hier $ beobachten bedeutet, dass Ihre „sehen“ nur durch das Attribut betroffen verändert sich und wird nicht betroffen sein, wenn Sie sollten das $ scope.collapsable innerhalb Ihrer Anweisung direkt ändern..

+1

Ich finde $ scope/$ element/$ attrs Namen hier verwirrend, weil Link keine Injektionen erhält, nur Positionsargumente. Also wären Umfang, Element und Attraktivität angemessener. – user1338062

+0

Gibt es einen Unterschied zwischen 'scope. $ Eval()' und javascript native 'eval()' Funktion? – Bloke

+1

@Bloke Hier ist eine SO Frage, die Sie hilfreich finden können. http://stackoverflow.com/questions/15671471/angular-js-how-does-eval-work-and-why-is-it-different-von-vanilla-eval – bingles

2

Da Angular 1.3 attrs $ beobachten scheint für nicht definierte Attribute auch auslösen, wenn Sie also für einen nicht definierten Attribut berücksichtigen wollen, müssen Sie etwas tun, wie:

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