Der einfachste Weg, um eine AngularJS-Scope-Variable von der statement zum Controller zu übergeben?

Was ist der einfachste Weg, um eine AngularJS Scope-Variable von Direktive an Controller zu übergeben? Alle Beispiele, die ich gesehen habe, scheinen so komplex zu sein, gibt es keine Möglichkeit, auf einen Controller von einer Direktive aus zuzugreifen und eine seiner Scope-Variablen zu setzen?

    Bearbeitet am 2014/8/25: Hier habe ich mich gegabelt.

    Danke @anvarik.

    Hier ist der JSFiddle . Ich habe vergessen, wo ich gegabelt habe. Aber das ist ein gutes Beispiel, das Ihnen den Unterschied zwischen = und @ zeigt

    Parent Scope

    // Update to see how parent scope interacts with component scope

    Attribute

    get: {{isolatedAttributeFoo}}
    set: // This does not update the parent scope.

    Binding

    get: {{isolatedBindingFoo}}
    set: // This does update the parent scope.

    Expression

    // And this calls a function on the parent scope.
     var myModule = angular.module('myModule', []) .directive('myComponent', function () { return { restrict:'E', scope:{ /* NOTE: Normally I would set my attributes and bindings to be the same name but I wanted to delineate between parent and isolated scope. */ isolatedAttributeFoo:'@attributeFoo', isolatedBindingFoo:'=bindingFoo', isolatedExpressionFoo:'&' } }; }) .controller('MyCtrl', ['$scope', function ($scope) { $scope.foo = 'Hello!'; $scope.updateFoo = function (newFoo) { $scope.foo = newFoo; } }]); 

    Warte bis angle die Variable ausgewertet hat

    Ich habe viel damit herumgespielt und konnte es auch mit der mit "=" im scope definierten Variable nicht zum Laufen bringen. Hier sind drei Lösungen, abhängig von Ihrer Situation.


    Lösung # 1


    Ich fand, dass die Variable nicht durch eckige ausgewertet wurde, wenn es an die Richtlinie übergeben wurde. Dies bedeutet, dass Sie darauf zugreifen und es in der Vorlage verwenden können, aber nicht innerhalb der Link- oder App-Controller-function, es sei denn, wir warten auf die Auswertung.

    Wenn sich Ihre Variable ändert oder durch eine Anfrage abgerufen wird, sollten Sie $observe oder $watch :

     app.directive('yourDirective', function () { return { restrict: 'A', // NB: no isolated scope!! link: function (scope, element, attrs) { // observe changes in attribute - could also be scope.$watch attrs.$observe('yourDirective', function (value) { if (value) { console.log(value); // pass value to app controller scope.variable = value; } }); }, // the variable is available in directive controller, // and can be fetched as done in link function controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) { // observe changes in attribute - could also be scope.$watch $attrs.$observe('yourDirective', function (value) { if (value) { console.log(value); // pass value to app controller $scope.variable = value; } }); } ] }; }) .controller('MyCtrl', ['$scope', function ($scope) { // variable passed to app controller $scope.$watch('variable', function (value) { if (value) { console.log(value); } }); }]); 

    Und hier ist der HTML-Code (erinnere dich an die Klammern!):

     

    Beachten Sie, dass Sie die Variable im Bereich nicht auf "=" setzen sollten, wenn Sie die function $observe verwenden. Außerdem habe ich festgestellt, dass Objekte als Strings übergeben werden. Wenn Sie also Objekte übergeben, verwenden Sie die Lösung # 2 oder den scope.$watch(attrs.yourDirective, fn) (oder # 3, wenn sich Ihre Variable nicht ändert).


    Lösung # 2


    Wenn Ihre Variable z. B. in einem anderen Controller erstellt wurde , aber nur warten muss, bis eckle diese ausgewertet hat, bevor Sie sie an den App-Controller gesendet haben, können Sie mit $timeout warten, bis $apply ausgeführt wurde. Außerdem müssen wir $emit , um es an den übergeordneten App-Controller zu senden (aufgrund des isolierten Bereichs in der Direktive):

     app.directive('yourDirective', ['$timeout', function ($timeout) { return { restrict: 'A', // NB: isolated scope!! scope: { yourDirective: '=' }, link: function (scope, element, attrs) { // wait until after $apply $timeout(function(){ console.log(scope.yourDirective); // use scope.$emit to pass it to controller scope.$emit('notification', scope.yourDirective); }); }, // the variable is available in directive controller, // and can be fetched as done in link function controller: [ '$scope', function ($scope) { // wait until after $apply $timeout(function(){ console.log($scope.yourDirective); // use $scope.$emit to pass it to controller $scope.$emit('notification', scope.yourDirective); }); }] }; }]) .controller('MyCtrl', ['$scope', function ($scope) { // variable passed to app controller $scope.$on('notification', function (evt, value) { console.log(value); $scope.variable = value; }); }]); 

    Und hier ist der HTML-Code (keine Klammern!):

     

    Lösung # 3


    Wenn sich Ihre Variable nicht ändert und Sie sie in Ihrer statement auswerten müssen, können Sie die function $eval verwenden:

     app.directive('yourDirective', function () { return { restrict: 'A', // NB: no isolated scope!! link: function (scope, element, attrs) { // executes the expression on the current scope returning the result // and adds it to the scope scope.variable = scope.$eval(attrs.yourDirective); console.log(scope.variable); }, // the variable is available in directive controller, // and can be fetched as done in link function controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) { // executes the expression on the current scope returning the result // and adds it to the scope scope.variable = scope.$eval($attrs.yourDirective); console.log($scope.variable); } ] }; }) .controller('MyCtrl', ['$scope', function ($scope) { // variable passed to app controller $scope.$watch('variable', function (value) { if (value) { console.log(value); } }); }]); 

    Und hier ist der HTML-Code (erinnere dich an die Klammern!):

     

    Sehen Sie sich auch diese Antwort an: https://stackoverflow.com/a/12372494/1008519

    Referenz für FOUC (Flash of unstyled content) Problem: http://deansofer.com/posts/view/14/AngularJs-Tips-and-Tricks-UPDATED

    Für Interessierte: Hier ist ein Artikel über den eckigen Lebenszyklus