2013-03-30 7 views
16

Ich habe eine Direktive in einem ng-Repeater, die eine Bereichseigenschaft setzen sollte. Bitte beachten Sie die Geige hier: http://jsfiddle.net/paos/CSbRB/Wie setze ich den Winkel-Controller-Objekteigenschaftswert aus der Direktive im Kindbereich ein?

Das Problem ist, dass der Umfang Eigenschaft wird als Attributwert wie folgt angegeben:

<button ng-update1="inputdata.title">click me</button> 

Die Richtlinie den Anwendungsbereich Eigenschaft festlegen soll inputdata.title zu einem gewissen Zeichenfolge . Dies funktioniert nicht:

app.directive('ngUpdate1', function() { 
    return function(scope, element, attrs) { 
     element.bind('click', function() { 
      scope.$apply(function() { 
       scope[ attrs.ngUpdate1 ] = "Button 1"; 
      }); 
     }); 
    }; 
}); 

Allerdings funktioniert die Zuordnung direkt:

scope["inputdata"]["title"] = "Button 1"; 

Können Sie mir bitte sagen, wie ich einen Umfang Eigenschaft mit festlegen. Notation in seinem Namen von einer Direktive?

PS: Der Grund, warum die Geige einen Repeater verwendet, liegt darin, dass die Direktiven in untergeordneten Bereichen liegen. Wenn sie sich in einem untergeordneten Bereich befinden, können Sie nicht in Bereichseigenschaften schreiben, die Grundelemente sind. Deshalb brauche ich eine Objekteigenschaft mit "." im Namen. Sehen Sie sich die lange Erklärung hier: What are the nuances of scope prototypal/prototypical inheritance in AngularJS?

Danke

+0

Eine unelegant Lösung die Zeichenfolge Form von '$ apply' zu verwenden wäre, zum Beispiel:.' Umfang gelten $ (attrs.ngUpdate1 + '=' + '"Button 1"'); '. –

+0

@Josh, für den Fall, dass Sie meine Antwort nicht sehen, ist die elegante Lösung, $ parse zu verwenden. –

Antwort

35

$parse wird Ihr Problem lösen.

<button ng-update1="inputdata.title"> 
app.directive('ngUpdate1', function($parse) { 
    return function(scope, element, attrs) { 
     var model = $parse(attrs.ngUpdate1); 
     console.log(model(scope)); // logs "test" 
     element.bind('click', function() { 
      model.assign(scope, "Button 1"); 
      scope.$apply(); 
     }); 
    }; 
}); 

Fiddle

Jedes Mal, wenn eine Richtlinie nicht ein Isolat Bereich verwenden und Sie einen Bereich Eigenschaft geben Sie ein Attribut, und Sie wollen, um den Wert zu ändern, $parse verwenden.

Wenn Sie den Wert nicht ändern müssen, können Sie $eval statt:

console.log(scope.$eval(attrs.ngUpdate1)); 
+0

Direkt an. Vielen Dank! – user681814

+0

Können Sie das gleiche tun, indem Sie ng-model als html-Attribut anstelle eines benutzerdefinierten verwenden, vorausgesetzt, dass Ihr html-Element eine Direktive ist und Sie den Code haben, den Sie hier in einer Link-Funktion dargestellt haben? – sonicblis

+0

@sonicblis, Ich schlage vor, eine neue Frage mit einer Geige zu stellen, da Sie nach einem ganz anderen Szenario fragen. Die Antwort hängt auch vom Typ des Bereichs ab, den die Richtlinie verwendet. Dies könnte helfen: http://stackoverflow.com/questions/11896732/ngmodel-and-component-with-isolated-scope –

2

nicht sicher, welche übergeordnete Ziel ist aber eine Möglichkeit, zwei Attribute zu erstellen ist, eine für das Zielobjekt und die andere für die Eigenschaft des Objekts:

<button ng-update1 obj="inputdata" prop="title"> 
app.directive('ngUpdate1', function() { 
    return function(scope, element, attrs) { 
     element.bind('click', function() { 
      scope.$apply(function() {     
       scope[ attrs.obj ][attrs.prop] = "Button 1";    

      }); 
     }); 
    }; 
}); 

DEMO: http://jsfiddle.net/CSbRB/9/

Alternativ vorhandene Format könnten Sie split() val ue Ihrer aktuellen ng-update1 Attribut und Verwendung Ergebnis-Array für Objekt und Eigenschaft in Notation

element.bind('click', function() { 
      var target=attrs.ngUpdate1.split('.'); 
      scope.$apply(function() {     
       scope[ target[0] ][target[1]] = "Button 1";    

      }); 
     }); 

DEMO mit beiden Ansätzen: http://jsfiddle.net/CSbRB/10/

Ein weiterer Ansatz, bei dem Sie einen isolierten Umfang in Richtlinie erstellen und in der Referenz passieren kann zu inputdata Objekt und von Attributeigenschaftsnamen (gleiche Markup als zweite Version) ziehen:

app.directive('ngUpdate3', function() { 
    return { 
     scope: { 
      targetObject: '=obj' 
     }, 
     link: function (scope, element, attrs) { 
      element.bind('click', function() { 
       scope.$apply(function() { 
        scope.targetObject[attrs.prop]='Button 3'; 

       }); 
      }); 
     } 
    } 
}); 

http://jsfiddle.net/CSbRB/11/

+0

Anstelle von zwei Attributen oder 'split()', verwenden Sie stattdessen $ parse (siehe meine Antwort). Mit einem isolate-Bereich können Sie auch direkt an die Objekteigenschaft binden, wenn Sie Folgendes möchten/müssen: '

+0

@MarkRajcok thanks .. versuchte, an Eigentum im isolierten Bereich früher zu binden und nicht sicher, warum es nicht funktionierte .. Docs für $ Parse sind schrecklich ... Ihre Kommentare helfen. Es scheint, als sollte es intuitivere Ansätze geben, als "$ parse" und dann "assign" zu verwenden. – charlietfl

+0

Ich hatte Probleme beim Binden an eine Eigenschaft in einem isolierten Bereich in Ihrer Geige. Ich denke, das Problem ist die ältere Version von Angular (1.0.0) in deiner Geige. –

Verwandte Themen