2016-03-20 5 views
1

Ich habe über ein Thema kommen und schuf eine JSFiddle to demonstrateAngualrJS: Warum ist der Komponentenumfang nicht bindend?

var myApp = angular.module("myApp", []); 
myApp.component("bar", { 
    transclude: true, 
    template: '<div ng-transclude></div>', 
    controller: function ($scope, $element, $attrs) { 
         $scope.msg = "Hello"; 
      setTimeout(function(){ 
       $scope.msg = "Goodbye"; 
       alert($scope.msg); 
      }, 3000) 
    } 
}); 

HTML:

<body ng-app="myApp"> 
    <bar> 
     {{ $parent.msg }} 
    </bar> 
</body> 

Wie Sie Ich habe einen Umfang Variable (msg), dass ich, nachdem ich einige Arbeit bin Aktualisierung sehen (setTimeout in diesem Fall). Im HTML scheint es nur eine unidirektionale Bindung zu geben, da "Goodbye" nie auf die Ansicht gerendert wird, wenn der Bereich der Komponente aktualisiert wird.

Bin ich richtig, $parent zu verwenden? Habe ich mein Ziel falsch verstanden? Bearbeite ich die Transkription richtig?

bearbeiten

soll ich sagen, dass setTimeout nur ein Beispiel ist, in meinem realen Welt Fall, dass ich für Komponenten http://www.createjs.com/ hinzufügen versuchen Statt setTimeout ich tatsächlich wurde das Hinzufügen eines ‚vollständig‘ Ereignis-Listener eines PreLoadJS LoadQueuehttp://www.createjs.com/docs/preloadjs/classes/LoadQueue.html

Antwort

3

Der Grund ist, dass Sie dies innerhalb setTimeout tun, die nicht im eckigen Kontext ist. Jedes Mal, wenn Sie den Bereich außerhalb des eckigen Kontextes aktualisieren, müssen Sie angle benachrichtigen, um einen Auszug auszuführen, um die Ansicht zu aktualisieren.

Angular bietet einen Service $timeout an, der sich um diese Aufgabe kümmert.

Versuchen:

controller: function ($scope, $element, $attrs, $timeout) { 
     $scope.msg = "Hello"; 
     $timeout(function(){ 
      $scope.msg = "Goodbye"; 
      alert($scope.msg); 
     }, 3000) 
} 

DEMO

+0

Danke für die schnellen Antworten - SetTimeout wurde nur ein Beispiel, die ich in meinem realen Fall ein Ereignis-Listener bin das Hinzufügen, aber ich denke, das gleiche gilt, es ist ein nicht-eckiger Kontext. Ich werde meine Frage bearbeiten, um mehr Details über meinen tatsächlichen Fall hinzuzufügen. –

+0

Gibt es eine Möglichkeit, einen Angular-Kontext zu übergeben, wenn mit einer nicht-eckigen Bibliothek gearbeitet wird? –

+0

Verwenden Sie '$ scope. $ Apply()' beim Aktualisieren des Bereichs außerhalb – charlietfl

0

Verwenden Sie den Dienst $timeout anstelle der rohen setTimeout-Funktion.

var myApp = angular.module("myApp", []); 
myApp.component("bar", { 
    transclude: true, 
    template: '<div ng-transclude></div>', 
    controller: function ($scope, $element, $attrs, $timeout) { 
      $scope.msg = "Hello"; 
      //Use $timeout 
      $timeout(function(){ 
      // 
      //setTimeout(function(){ 
       $scope.msg = "Goodbye"; 
       //alert($scope.msg); 
      }, 3000) 
    } 
}); 

Der $timeout Service ist der AngularJS Wrapper für die setTimeout Funktion. Es verspricht Versprechen und ist in den Digest-Zyklus von AngularJS Framework integriert.

Weitere Informationen finden Sie unter AngularJS $timeout Service API Reference.

0

mit $timeout statt setTimeout Ihr Problem wie die anderen Antworten beheben erwähnen, aber mit $parent ist nie eine gute Idee. Es macht Ihren Code sehr fragil. Zum Beispiel versuchen Sie eine ng-wenn um Ihre {{$parent.msg}} Bindung und beachten Sie, dass es bricht()

Eine bessere Lösung wäre, Komponenten Bindungen zu verwenden, etwas aus der Komponente zu übergeben. z.B.

JS

var myApp = angular.module("myApp", []); 
myApp.component("bar", { 
    transclude: true, 
    template: '<div ng-transclude></div>', 
    bindings: { 
     msg: '=' 
    }, 
    controller: function ($scope, $element, $attrs, $timeout) { 
     var self = this; 
     self.msg = "Hello"; 
     $timeout(function(){ 
     self.msg = "Goodbye"; 
     alert(self.msg); 
     }, 3000) 
    } 
}); 

HTML

<body ng-app="myApp"> 
    <bar msg="vm.myMsg"> 
     {{ vm.myMsg }} 
    </bar> 
</body> 

Arbeitslösung: http://jsfiddle.net/rc8zs4nk/

Verwandte Themen