Передать параметр в функцию контроллера Angularjs из директивы

0

У меня есть директива AngularJs, которая создает свойство и функцию обратного вызова в своей изолированной области:

.directive('testButton', [function () {
  return {
    restrict: 'A',
    controller: 'TestDirectiveController as vmDirective',
    scope: {     
        myCallBack:'&myCallBack',
        myVariable: '=myVariable'
    },
    template: function (element, attrs) {
        return '<button data-ng-click="vmDirective.onButtonClicked(2)">Set myVariable = 2</button>';
    }
};}])

В директиве нажата кнопка, и она выполняет функцию onButtonClicked. Затем он устанавливает переменную области видимости и вызывает функцию $scope.myCallBack.

Функция callBack выполняется и выполняет следующие действия: console.log($scope.linkedVariable);

Проблема заключается в том, что $scope.linkedVariable еще не обновлен, и на этом этапе $scope.linkedVariable все еще является предыдущим значением.

Когда я завершаю вышеуказанный код в setTimeout извлекается правильное значение: setTimeout(function(){console.log($scope.linkedVariable)}, 2000);

Мой вопрос: как правильно передать значение функции onCallBack.

Пожалуйста, смотрите полный пример кода ниже:

   angular.module('application',[])

   .directive('testButton', [function () {
      return {
         restrict: 'A',
         controller: 'TestDirectiveController as vmDirective',
         scope: {     
              myCallBack:'&myCallBack',
              myVariable: '=myVariable'
         },
         template: function (element, attrs) {
            return '<button data-ng-click="vmDirective.onButtonClicked(2)">Set myVariable = 2</button>';
         }
       };
    }])

  .controller("TestDirectiveController", ['$scope', function($scope){
       var self = this;
       self.onButtonClicked = function(value){
          $scope.myVariable = value;
          $scope.myCallBack();
       };
   }])

  .controller("TestController", ['$scope', function($scope){
      var self = this;
      $scope.linkedVariable = null;

      self.onCallBack = function(){
      console.log($scope.linkedVariable);
      setTimeout(function(){console.log($scope.linkedVariable)}, 2000);
    };
 }])

HTML:

<div data-ng-controller="TestController as vm">
   <div data-test-button="" data-my-call-back="vm.onCallBack()" data-my-variable="linkedVariable"></div>
</div>

jsfiddle: http://jsfiddle.net/ff5ck0da/1/

Теги:
angularjs-scope
angularjs-directive

2 ответа

2
Лучший ответ

Я нашел более приемлемый/правильный способ преодолеть мою проблему благодаря http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-3-isolate-scope-and-function-parameters.

Вместо того, чтобы обращаться к $scope.linkedVariable в контроллере, теперь я принимаю значение как параметр функции.

Чтобы заставить это работать, мне пришлось изменить объявление функции в HTML:

data-my-call-back="vm.onCallBack"

Объявление функции контроллера:

self.onCallBack = function(myVariable){
    console.log(myVariable);        
};

директива затем может вызвать функцию:

self.onButtonClicked = function(value){        
    $scope.myCallBack()(value);
};

См. Обновленную версию JSFiddle: http://jsfiddle.net/ff5ck0da/9/

0

Вы даже можете изменить настройку на

setTimeout(function(){console.log($scope.linkedVariable)}, 0);

это приведет к разрешению переменной в нижней части стека асинхронов. И, таким образом, оцените после выполнения цикла углового дайджеста (по существу, задано значение переменной)

Если вы не хотите использовать setimeout, вы можете использовать это:

self.onCallBack = function(){
        var accessor = $parse($scope.linkedVariable);
        $scope.value = angular.copy(accessor($scope.$parent));
        console.log($scope.linkedVariable);
};

здесь вы, по сути, говорите угловатым, чтобы не использовать копию, а фактическую родительскую переменную.

  • 0
    Я бы не хотел использовать setTimeout как он кажется немного хакерским.
  • 0
    @TjaartvanderWalt Я согласен увидеть мой обновленный ответ
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню