Javascript 如何将数据从指令传递到控制器

Javascript 如何将数据从指令传递到控制器,javascript,angularjs,d3.js,Javascript,Angularjs,D3.js,我在我的应用程序中构建了一个自定义指令,它利用了D3.js。我希望在用户单击D3可视化中的节点时,能够进行API调用以加载更多数据。这将需要抓取与单击的节点关联的数据,并将其传递回我的控制器。然后,控制器处理调用函数以检索更多数据 首先,我只是尝试记录与用户在我的控制器中单击的节点相关联的数据。我的问题是,该数据在我的控制器中未定义 相关指令代码: angular.module('gameApp') .directive('gmLinkAnalysis', gmLinkAnalysis);

我在我的应用程序中构建了一个自定义指令,它利用了D3.js。我希望在用户单击D3可视化中的节点时,能够进行API调用以加载更多数据。这将需要抓取与单击的节点关联的数据,并将其传递回我的控制器。然后,控制器处理调用函数以检索更多数据

首先,我只是尝试记录与用户在我的控制器中单击的节点相关联的数据。我的问题是,该数据在我的控制器中未定义

相关指令代码:

angular.module('gameApp')
  .directive('gmLinkAnalysis', gmLinkAnalysis);

gmLinkAnalysis.$inject = ['$location', 'd3'];

function gmLinkAnalysis($location, d3) {

  var directive = {
    restrict: 'E',
    templateUrl: '/app/gmDataVis/gmLinkAnalysis/gmLinkAnalysis.directive.html',
    scope: {
      data: '=',
      logNode: '&'
    },
    link: function(scope) {

      ...

      function click(d) {
        scope.logNode(d);
      }
    }
  };
  return directive;
}
HTML:


如果我用诸如“hello world”(
log node=“connections.logNode('hello world')”
)之类的字符串替换html中的
d
,它将被正确记录。很明显,我的问题在于没有正确地将数据作为html中的参数传递。如何执行此操作?

您需要在调用中指定参数:

所以在你的指令中应该是

function click(d) {
  scope.logNode({d: d})
}
以下是一个例子:

您可以将附加某些方法的模型传递到指令中,但我个人更喜欢使用
$.broadcast
服务来保持代码库的干净

指示

function click(d) {
   $rootScope.$broadcast('someEvent', d);
 }
控制器

angular.module('gameApp')
   .controller('ConnectionsController', ConnectionsController);

 function ConnectionsController() {
   var vm = this;

   vm.$on('someEvent', function(event, data) {
     console.log(data)
   });
 }

如果您仍然认为传递方法会对您有好处,那么下面是一个通过数据模型将方法传递给指令的方法

$broadcast确实很方便,但是它会带来开销(就摘要等而言),并且会在以后产生可维护性问题。但是这确实有效。@heavyhorse我非常不同意,使用
$broadcast
只有在将来任何方法名称发生更改时,才应该有“unmatched”事件。方法调用将更加准确,数据模型也将不那么复杂。此外,调试和类型检查也会更容易。
function click(d) {
   $rootScope.$broadcast('someEvent', d);
 }
angular.module('gameApp')
   .controller('ConnectionsController', ConnectionsController);

 function ConnectionsController() {
   var vm = this;

   vm.$on('someEvent', function(event, data) {
     console.log(data)
   });
 }