2016-09-19 132 views
0

我有一個帶有倒計時的小腳本,通過directive創建,如果controller中的$scope值爲true,則該腳本開始。這是html代碼:將範圍值從指令傳遞到控制器 - AngularJS

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

其次directive的代碼:

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(); 
     } 
     }); 
    } 
    } 
}); 

倒計時工作正常,但controller內,如果$scope.count === 0,應該有一個alert()但它不是加工。

這是一個Plnkr與完整的代碼。您知道如何將$scope.count的值傳遞給controller並解決此問題嗎?提前感謝您的回覆!

+0

它看起來像你使用這個指令父範圍,即不隔離指令範圍,因爲你沒有範圍:{...}在你的指令上面的代碼。這意味着你應該能夠簡單地在控制器中放置一個$ scope。$ watch('count',...)來監視範圍變量的變化。如果你想使用獨立的範圍,那麼你可以在你的指令中放置一個方法綁定範圍:{countdown:'&'},然後你可以在控制器中爲該方法設置一個綁定,然後從你的指令中調用該方法。 –

回答

1

您可以使用$廣播用相同的代碼來實現這一目標。

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(); 
    } 
    }); 
} 

請找工作plunker here.

+0

Maciej的解決方案也是正確的,但這是更好的,因爲它使用'範圍'作爲孤立的。謝啦! –

2

I.子範圍指令。

您沒有創建隔離範圍,因此最簡單的解決方案是刪除控制器中的from屬性和init count範圍變量。所以:

與沒有隔離的範圍(子作用域)指令
//controller code 
//init variable 
$scope.count=3; 

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

實施例:

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。隔離範圍指令

你也可以做同樣的事情用隔離範圍,它需要通過=(雙向綁定)傳遞變量。例如:

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

你的解決方案看起來很合理,但你可以通過修改應用於該指令的'start-if'屬性來編輯該文件嗎? –

+0

@ d_z90我在第一個代碼示例變量start中加入。因此,在控制器中創建變量,然後在指令中觀察它,在回調中您可以運行倒計時。 –

相關問題