2016-09-19 5 views
0

У меня есть небольшой сценарий с обратным отсчетом, созданным через directive, который начинается, если значение $scope внутри controller является true. Это html код:Pass значение Сферы из директивы к контроллеру - 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 тоже правильно, но это лучше, поскольку он использует 'scope' как изолированный. Спасибо чувак! –

2

I. Child scope директива.

Вы не создали изолированную область видимости, поэтому самым простым решением является удаление атрибута 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. Итак, создайте переменную в контроллере, затем посмотрите ее в директиве, в обратном вызове. Вы можете запустить обратный отсчет. –

Смежные вопросы