Контроллер угловой директивы не видит переданное обновление параметров
У меня проблемы с использованием контроллера в угловой директиве. Когда данные передаются в директиву в качестве параметра, я хочу выполнить простое преобразование и передать его в дочернюю директиву. При инициализации параметр пуст. Он передается с событием ng-click.
angular.module('myApp', [])
.directive('testDirective', function() {
var controller = function() {
var vm = this;
// when 'datasoure' is bound to the controller?
console.log(vm);
// I have to do some transformations here when the data is pushed to the directive
if (vm.datasource != undefined) {
vm.direlements = vm.datasource.elements;
}
};
return {
controller: controller,
controllerAs: 'ctrl',
bindToController: true,
scope: {
datasource: '=',
},
template: '<div><li ng-repeat="item in ctrl.direlements">{{item}}</li></div>'
}
})
.controller('TestCtrl', function() {
var vm = this,
current = {};
vm.buttonClick = function() {
console.log('buttonClick');
vm.current = {
elements: [{
'a': 1
}, {
'b': 2
}]
}
}
});
HTML:
<body ng-app="myApp">
<div ng-controller="TestCtrl as test">
<button ng-click="test.buttonClick()">push me</button>
<test-directive datasource="test.current"></test-directive>
</div>
</body>
Здесь ничего не происходит. Похоже, контроллер не отслеживает изменения параметров. Plunkr
2 ответа
У вас было две проблемы в коде.
Итак, во-первых, вы устанавливаете переменную контроллера direlements
только в инициализации контроллера, но в то время переменная не определена, потому что вы устанавливаете ее, когда нажимаете. Так что вам нужно $watch, чтобы поддерживать его в актуальном состоянии и вводить $ scope в контроллер:
vm.direlements = [];
$scope.$watch(function() {
return vm.datasource;
}, function(oldValue, newValue) {
if(typeof(newValue) !== 'undefined') {
vm.direlements = vm.datasource.elements;
}
});
Затем внутри вашего основного контроллера вы определяете в начале тока локальную переменную, но вы хотите, чтобы она была переменной vm, поэтому вы должны использовать это:
var vm = this;
vm.current = {};
Все остальные вещи в порядке.
Итак, вот ваш полный пример:
Как переданные данные datasource
, он ищет только изменение данных, а не новую переменную, созданную вами, vm.direlements
, Итак, сделайте это:
<li ng-repeat="item in ctrl.datasource.elements">
Это сделает вашу работу.
Или, если вы хотите сделать то же самое, что вы сделали, вы можете посмотреть его с помощью $watch
как показано ниже:
$scope.$watch(angular.bind(this, function () {
return this.datasource;
}), function (newVal) {
vm.direlements = vm.datasource.elements;
});
Не забудьте ввести $scope
в контроллере.
Вот пробник с обоими решениями.
Всего наилучшего.