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

Javascript AngularJS-将两个指令绑定/链接在一起,javascript,angularjs,angularjs-directive,Javascript,Angularjs,Angularjs Directive,将两个指令链接/绑定在一起的首选方式是什么?我有一个带有两个指令的控制器,第一个指令是select元素,在选择option之后,第二个指令应该处理所选项目的值 应用程序代码: var app = angular.module('plunker', []); app.controller('MainCtrl', function() { var sharedData = { selectedId: '' }; var vm = this; vm.sharedData = shar

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

应用程序代码:

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);
      });
    }
  };
}]);
var-app=angular.module('plunker',[]);
应用程序控制器('MainCtrl',函数(){
var sharedData={selectedId:''};
var vm=这个;
vm.sharedData=sharedData;
});
app.directive('directiveA',['$compile',function($compile){
返回{
限制:'E',
范围:{
selectedId:“=”
},
模板:“选择选项指令A,所选ID:{{vm.sharedData.selectedId}

”, bindToController:对, controllerAs:'vm', 控制器:函数(){ vm=这个; vm.sharedData={ 可用性选择:[ {Id:1,名称:'Option 1'}, {Id:2,名称:'Option 2'}, {Id:3,名称:'Option 3'}, {Id:4,名称:'Option 4'} ] } vm.logMessage=logMessage; 功能日志信息(选择EDID){ console.log('directiveA:'+selectedId); } }, 链接:函数($scope、elem、attr、ctrl){ 属性$observe('selectedId',函数(selectedId){ ctrl.logMessage(选择EDID); }); } }; }]); app.directive('directiveB',['$compile',function($compile){ 返回{ 限制:'E', 范围:{ selectedId:“=” }, 模板:“指令B,所选ID:{{vm.sharedData.selectedId}

”, bindToController:对, controllerAs:'vm', 控制器:函数(){ vm=这个; vm.logMessage=logMessage; 功能日志信息(选择EDID){ log('directiveB:'+selectedId); } }, 链接:函数($scope、elem、attr、ctrl){ 属性$observe('selectedId',函数(selectedId){ ctrl.logMessage(选择EDID); }); } }; }]);
HTML代码:

<!DOCTYPE html>
<html data-ng-app="plunker" data-ng-strict-di>
  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link href="style.css" rel="stylesheet" />
    <script data-semver="1.4.1" src="https://code.angularjs.org/1.4.1/angular.js" data-require="angular.js@1.4.x"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl as vm">
    <p>MainCtrl, selected ID: {{vm.sharedData.selectedId}}</p>
    <directive-a data-selected-id="vm.sharedData.selectedId"></directive-a>
    <directive-b data-selected-id="vm.sharedData.selectedId"></directive-b>
  </body>

</html>

安古拉斯普朗克
文件。写(“”);
MainCtrl,所选ID:{{vm.sharedData.selectedId}

以下是一个Plunker示例:

我做错了什么


致以最诚挚的问候,

关键问题在于您对隔离作用域的使用:

scope: {
  selectedId: '='
},
使用controllerAs绑定:

controllerAs: 'vm',
这基本上是将视图模型放在指令范围内,通过您在controllerAs中指定的别名访问。因此,基本上在您的html中:

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

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

您需要做的是更多地遵循以下原则:


编辑


TLDR:我建议在使用独立作用域时使用唯一的视图模型别名(Controllera),以正确反映它们不是同一视图模型的事实。

您有两条指令要求在同一元素上使用独立作用域,这是不允许的。这是一个重复的问题。如果我正确理解了您的需求,那么我认为您需要使用require来表示两个控制器之间的引用,嗯,就是在同一个元素()上有两个指令,但在这里,我在同一个变量上有两个独立的指令。我希望避免使用require参数-这两个指令应该是独立的。只是要补充:基本上,我所做的是让MainCtrl vm存储selectedId,然后通过MainCtrl视图模型(mainVm)双向绑定到两个子指令。然后将此属性绑定到相应视图模型的子指令:aVm和bVm。当他们更改或访问这些属性时,实际上他们正在访问父mainVm.selectedId属性,因为隔离作用域声明中存在双向绑定。谢谢,这就是我需要的!我忘记了“controllerAs”模型的不同名称。很高兴我能提供帮助:)理解作用域始终是angular的一个重要部分,controllerAs(以及bindToController)在帮助消除对象/变量绑定的模糊性方面做了很大的工作。因此,很高兴看到您尝试使用这种模式。同时,如果您的帖子有帮助,我们也将非常感谢您将帖子标记为答案;)祝你一切顺利!