2016-09-19 4 views
0

Ich habe ein kleines Skript mit einem Countdown, erstellt durch eine directive, die startet, wenn ein $scope Wert innerhalb der controller ist true. Dies ist der html Code:Pass scope Wert von Direktive zu Controller - AngularJS

<countdown from="3" start-if="{{startCountdown}}"></countdown> 

durch den Code des directive Gefolgt:

app.directive('countdown', function ($interval) { 
    return { 
    restrict: 'E', 
    template: '{{count}}', 
    controller: function($scope, $element, $attrs) { 
     $scope.count = $attrs.from; 

     function countdown(){ 
     var intervalID = $interval(function() { 
      if ($scope.count > 0) { 
      $scope.count--; 
      } else { 
      $interval.cancel(intervalID); 
      } 
     }, 1000); 
     } 

     $attrs.$observe('startIf', function(value) { 
     if (value) { 
      countdown(); 
     } 
     }); 
    } 
    } 
}); 

Der Countdown läuft einwandfrei funktioniert, aber innerhalb des controller, wenn $scope.count === 0, sollte es eine alert() sein, aber es ist nicht Arbeiten.

Dies ist ein Plnkr mit dem vollständigen Code. Wissen Sie, wie Sie den Wert $scope.count an die controller übergeben und dieses Problem lösen können? Vielen Dank im Voraus für Ihre Antworten!

+0

Es sieht aus wie Sie den übergeordneten Rahmen dieser Richtlinie verwenden, also nicht Rahmen für die Richtlinie isoliert, weil Sie keinen Raum haben: {...} in der Richtlinie Code oben. Das bedeutet, dass Sie in der Lage sein sollten, einfach einen $ scope. $ Watch ('count', ...) in den Controller zu setzen, um nach der Änderung der Scope-Variablen Ausschau zu halten. Wenn Sie einen isolierten Bereich verwenden möchten, können Sie einen Methodenbindungsbereich festlegen: {countdown: '&'} in Ihrer Anweisung. Anschließend können Sie im Controller eine Bindung für diese Methode einrichten und diese Methode anschließend von Ihrer Anweisung aufrufen. –

Antwort

1

Sie können $ ausgestrahlt erreichen verwenden, um dies mit dem gleichen Code.

controller: function($scope, $element, $attrs, $rootScope) { 
    $scope.count = $attrs.from; 

    function countdown(){ 
    var intervalID = $interval(function() { 
     $rootScope.$broadcast('counterVal',{ 
      countVal:$scope.count 
     }); 
     if ($scope.count > 0) { 
     $scope.count--; 

     } else { 
     $interval.cancel(intervalID); 
     } 
    }, 1000); 
    } 

    $attrs.$observe('startIf', function(value) { 
    if (value) { 
     countdown(); 
    } 
    }); 
} 

Sie finden den Arbeits Plunker here.

+0

Maciej Lösung ist auch richtig, aber das ist besser, da es das 'scope' als isoliert verwendet. Danke, Mann! –

2

I. Richtlinie für den Kindbereich.

Sie haben keinen isolierten Bereich erstellt. Die einfachste Lösung ist das Entfernen von from Attribut und init count Bereichsvariablen im Controller. Also:

//controller code 
//init variable 
$scope.count=3; 

//directive code 
//manipulate variable 
$scope.count--; 

Beispiel mit der Richtlinie ohne isolierten Rahmen (Kinder scope):

var app=angular.module("app",[]); 
 
app.controller("controller",function($scope,$timeout){ 
 

 
    $scope.count=2; 
 
    $scope.start=false;//start countdown flag 
 

 

 
    $scope.$watch("count",function(val){ 
 
    
 
    console.log("Count is changed to:"+val); 
 
     
 
    }); 
 
    
 
}); 
 

 
app.directive("myDirective",function($timeout){ 
 

 
    return{ 
 
    restrict:"E", 
 
    template:"{{count}}", 
 
    link:function(scope){ 
 
     
 
     scope.count++;//example change 
 
    
 
     $timeout(function() { scope.count++; },2000);//example change 
 

 
     scope.$watch("start",function(){ 
 
      
 
      //here we watch changes in start scope variable 
 
      //here start countdown 
 

 
     }); 
 
     
 
    } 
 
    } 
 
    
 
    
 
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<div ng-app="app" ng-controller="controller"> 
 
    <my-directive></my-directive> 
 
</div>

II. Isolierte Umfang Richtlinie

Sie auch die gleiche Sache mit isoliertem Umfang tun kann, müssen sie Variable vorbei =(Zwei-Wege-Bindung). Beispiel:

var app=angular.module("app",[]); 
 
    app.controller("controller",function($scope){ 
 

 
     $scope.count=2; 
 
     
 
     $scope.$watch("count",function(val){ 
 
     
 
     console.log("Count is changed to:"+val); 
 
      
 
     }); 
 
     
 
    }); 
 

 
    app.directive("myDirective",function($timeout){ 
 

 
     return{ 
 
     restrict:"E", 
 
     scope:{ 
 
     count:"="//pass variable to isolated scope 
 
     }, 
 
     template:"{{count}}", 
 
     link:function(scope){ 
 
      
 
      scope.count++;//example change 
 
     
 
      $timeout(function() { scope.count++; },2000);//example change 
 
      
 
     } 
 
     } 
 
     
 
     
 
    });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
    <div ng-app="app" ng-controller="controller"> 
 
     <my-directive count="count" ></my-directive> 
 
    </div>

+0

Ihre Lösung scheint vernünftig, aber können Sie die Datei bearbeiten, indem Sie auch das Attribut 'start-if' für die Anweisung ändern? –

+0

@ d_z90 Ich habe im ersten Codebeispiel Variablenstart hinzugefügt. Also erstelle eine Variable im Controller und beobachte sie dann in der Direktive, im Callback. Du kannst einen Countdown ausführen. –

Verwandte Themen