将范围值从指令传递到控制器 - AngularJS
我有一个带有倒计时的小脚本,通过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
并解决此问题吗?提前感谢您的回复!
您可以使用$广播用相同的代码来实现这一目标。
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.
Maciej的解决方案也是正确的,但这是更好的,因为它使用'范围'作为孤立的。谢啦! –
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>
你的解决方案看起来很合理,但你可以通过修改应用于该指令的'start-if'属性来编辑该文件吗? –
@ d_z90我在第一个代码示例变量start中加入。因此,在控制器中创建变量,然后在指令中观察它,在回调中您可以运行倒计时。 –
它看起来像你使用这个指令父范围,即不隔离指令范围,因为你没有范围:{...}在你的指令上面的代码。这意味着你应该能够简单地在控制器中放置一个$ scope。$ watch('count',...)来监视范围变量的变化。如果你想使用独立的范围,那么你可以在你的指令中放置一个方法绑定范围:{countdown:'&'},然后你可以在控制器中为该方法设置一个绑定,然后从你的指令中调用该方法。 –