0

我在角度指令中使用 controllerAs 时遇到问题。当数据作为参数传递给指令时,我想做一些简单的转换并将其传递给子指令。初始化参数为空。它通过 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

4

2 回答 2

1

您在代码中有两个问题。

因此,首先,您direlements仅在控制器的 init 上设置控制器变量,但当时该变量未定义,因为您在单击时设置了它。所以你需要一个 $watch 来保持更新并将 $scope 注入控制器:

vm.direlements = [];
      $scope.$watch(function() {
        return vm.datasource;
      }, function(oldValue, newValue) {
          if(typeof(newValue) !== 'undefined') {
            vm.direlements = vm.datasource.elements;
          }
      });

然后在你的主控制器中,你在开始时将 current 定义为局部变量,但你希望它作为 vm 变量,所以你应该使用这个:

var vm = this;
vm.current = {};

其他一切都还好。

所以这里是你的完整示例:

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

于 2017-05-25T13:04:21.487 回答
0

由于传递的数据是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控制器。

这是尝试使用两种解决方案的plunker 。

一切顺利。

于 2017-05-25T12:51:16.080 回答