Контроллер угловой директивы не видит переданное обновление параметров

У меня проблемы с использованием контроллера в угловой директиве. Когда данные передаются в директиву в качестве параметра, я хочу выполнить простое преобразование и передать его в дочернюю директиву. При инициализации параметр пуст. Он передается с событием 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 = {};

Все остальные вещи в порядке.

Итак, вот ваш полный пример:

http://plnkr.co/edit/sALFVkSPIxVPOS42nOGu?p=preview

Как переданные данные 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 в контроллере.

Вот пробник с обоими решениями.

Всего наилучшего.

Другие вопросы по тегам