2013-07-10 10 views
26

Ich muss ein Root-Scope-Attribut innerhalb eines Callback innerhalb einer Direktive ändern. Aber die Richtlinie liegt in einem inneren Bereich, der durch eine switch-Direktive geschaffen wurde.So ändern Sie den Bereich innerhalb einer Direktive in AngularJs

HTML

<div ng-app="app" ng-controller='AppController'> 
    <p>Selected: {{ selected }}</p> 
    <div ng-switch on="selected"> 
     <div ng-switch-default> 
      <p>Item: {{ selected }}</p> 
      <custom-tag selected-item="selected" /> 
     </div> 
     <div ng-switch-when="New value"> 
      <p>Worked</p> 
     </div> 
    </div> 
</div> 

JavaScript

angular.module('app', [])  
    .directive("customTag", [function() { 
    return { 
     restrict: "E", 
     replace: true, 
     template: "<input type='button' value='Click me' />", 

     link: function (scope, element, attrs) { 
      element.bind('click', function() { 
       scope[attrs.selectedItem] = "New value"; 
       scope.$apply(); 
      }); 
     } 
    }; 
}]); 

function AppController($scope) { 
    $scope.selected = 'Old value'; 
} 

Fiddle: http://jsfiddle.net/nJ7FQ/

Mein Ziel ist es, "Neuer Wert" im ausgewählten Bereich angezeigt werden soll. Wie kann ich erreichen, was ich versuche zu tun? Was mache ich falsch?

Außerdem, wie ich versuche, eine Komponente zu machen. Gibt es eine Möglichkeit, dasselbe zu tun, aber mit einem isolierten Umfang?

Antwort

19

Ich aktualisierte die Geige, musste im Grunde zu den Eltern gehen, um die richtige "ausgewählte" Variable zu erhalten, auch den isolate scope = verwendet, um eine bidirektionale Bindung zwischen dem übergebenen Wert und dem internen Modell zu erhalten.

http://jsfiddle.net/nJ7FQ/2/

angular.module('app', []) 

    .directive("customTag", [function() { 
    return { 
     restrict: "E", 
     replace: true, 
     template: "<input type='button' value='Click me' />", 
     scope: {model:'='}, 

     link: function (scope, element, attrs) { 
      element.bind('click', function() { 
       scope.model[attrs.selectedItem] = "New value"; 
       scope.$apply(); 
      }); 
     } 
    }; 
}]); 

function AppController($scope) { 
    $scope.selected = 'Old value'; 
} 

und die HTML-

<div ng-app="app" ng-controller='AppController'> 
    <p>Selected: {{ selected }}</p> 
    <div ng-switch on="selected"> 
     <div ng-switch-default> 
      <p>Item: {{ selected }}</p> 
      <custom-tag selected-item="selected" model="$parent" /> 
     </div> 
     <div ng-switch-when="New value"> 
      <p>Worked</p> 
     </div> 
    </div> 
</div> 

aktualisiert die Geige Ihre ursprüngliche Lesart des Objektes aus dem Attribut zu verwenden: http://jsfiddle.net/nJ7FQ/4/

+0

Ich mochte besser Ihre erste Lösung (http://jsfiddle.net/nJ7FQ/2/) Es scheint irgendwie sauberer. Aber warum sollte ich $ parent.selected verwenden, wenn Child Scopes nach meinem Verständnis alle Eigenschaften des Parents erbt? – Fernando

+1

Nun, wenn Sie das ausgewählte Element für das vererbte Element ändern, wird die ausgewählte Variable des übergeordneten Bereichs nicht geändert, indem Sie zum übergeordneten Element wechseln und die Variable für dieses Element ändern. Wenn der untergeordnete Wert gelesen wird, wird das Element angezeigt Elternteil. Wenn Sie die ausgewählte Eigenschaft des untergeordneten Bereichs ändern, wird sie zu einer neuen Eigenschaft im untergeordneten Bereich und nicht mehr erben. (Ich weiß, es ist verwirrend) Dies ist JavaScript-Prototyp Erbe, wenn Sie Google es wollen. – shaunhusain

+0

Es ist vollkommen klar! Danke vielmals. – Fernando

15

ich die jsfiddle ein wenig verbessert:

angular.module('app', []) 

    .directive("customTag", ['$parse', function ($parse) { 
    return { 
     restrict: "E", 
     replace: true, 
     template: "<input type='button' value='Click me' />", 

     link: function (scope, element, attrs) { 
      element.bind('click', function() { 
       scope.$apply(function() { 
        $parse(attrs.selectedItem).assign(scope.$parent, "New value"); 
       }); 
      }); 
     } 
    }; 
}]); 

function AppController($scope) { 
    $scope.selected = { 'foo': 'Old value' }; 
} 

http://jsfiddle.net/nJ7FQ/15/

Auf diese Weise der Umfang Wert, möchten Sie eine Objekteigenschaft sein wie selected.foo im Beispiel können auch geändert werden. Außerdem entfernte ich den Bereichsparameter und wies die Anweisung an, immer den übergeordneten Bereich zu verwenden. Und schließlich wickelte ich den Click-Handler in den Callback $apply (siehe here zum Beispiel). Besser wäre natürlich ngClick anstelle der element.bind() zu verwenden.

+0

BINGO! Gute Lösung, um den übergeordneten Bereich zuzuweisen. Ideal für so etwas wie Modals – saike

Verwandte Themen