У меня есть директива 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/
Я нашел более приемлемый/правильный способ преодолеть мою проблему благодаря 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/
Вы даже можете изменить настройку на
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);
};
здесь вы, по сути, говорите угловатым, чтобы не использовать копию, а фактическую родительскую переменную.
setTimeout
как он кажется немного хакерским.