AngularJS - 将两个指令绑定/链接在一起

时间:2015-06-22 20:12:23

标签: javascript angularjs angularjs-directive

将两个指令链接/绑定在一起的首选方法是什么?我有一个带有两个指令的控制器,第一个指令是一个选择元素,在选择选项后,第二个指令应该处理所选的项值。

应用代码:

/Developer/NVIDIA/CUDA-samples/7_CUDALibraries/conjugateGradientPrecond

HTML code:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function() {
  var sharedData = { selectedId: '' };

  var vm = this;

  vm.sharedData = sharedData;
});

app.directive('directiveA', ['$compile', function($compile) {
  return {
    restrict: 'E',
    scope: {
      selectedId: '='
    },
    template: '<select data-ng-model="vm.sharedData.selectedId" data-ng-options="currentSelect.Id as currentSelect.Name for currentSelect in vm.sharedData.availableSelects track by currentSelect.Id"><option value="">Select option</option></select><p>Directive A, selected ID: {{vm.sharedData.selectedId}}</p>',
    bindToController: true,
    controllerAs: 'vm',
    controller: function() {
      vm = this;

      vm.sharedData = {
        availableSelects: [
          {Id:1, Name: 'Option 1'},
          {Id:2, Name: 'Option 2'},
          {Id:3, Name: 'Option 3'},
          {Id:4, Name: 'Option 4'}
        ]
      }
      vm.logMessage = logMessage;

      function logMessage(selectedId) {
        console.log('directiveA: ' + selectedId);
      }
    },
    link: function($scope, elem, attr, ctrl) {
      attr.$observe('selectedId', function(selectedId) {
        ctrl.logMessage(selectedId);
      });
    }
  };
}]);

app.directive('directiveB', ['$compile', function($compile) {
  return {
    restrict: 'E',
    scope: {
      selectedId: '='
    },
    template: '<p>Directive B, selected ID: {{vm.sharedData.selectedId}}</p>',
    bindToController: true,
    controllerAs: 'vm',
    controller: function() {
      vm = this;

      vm.logMessage = logMessage;

      function logMessage(selectedId) {
        console.log('directiveB: ' + selectedId);
      }
    },
    link: function($scope, elem, attr, ctrl) {
      attr.$observe('selectedId', function(selectedId) {
        ctrl.logMessage(selectedId);
      });
    }
  };
}]);

这是一个Plunker示例:

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

我做错了什么?

最诚挚的问候,

1 个答案:

答案 0 :(得分:1)

关键问题围绕您使用隔离范围:

scope: {
  selectedId: '='
},

使用controllerAs绑定:

controllerAs: 'vm',

基本上,基本上,它将视图模型置于指令范围内,通过您在controllerAs中分配的别名进行访问。所以基本上在你的HTML中去了:

<directive-a data-selected-id="vm.sharedData.selectedId"></directive-a>

您实际上是在访问指令 - 视图模型,而不是MainCtrl视图模型。因为你将directive-a设置为具有隔离范围...这是一个与MainCtrl隔离的新范围。

您需要做的更多的是以下几行:

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

编辑

TLDR:我建议在使用隔离范围时,要有唯一的视图模型别名(controllerAs),以正确反映它们不是同一个视图模型的事实。