【问题标题】:Passing function to directive that directive should execute将函数传递给指令应该执行的指令
【发布时间】:2025-12-20 13:55:12
【问题描述】:

我对将'&' 与隔离范围的rowClick 一起使用感到困惑。看看下面的代码。在一次代码审查中,我被告知这是一种反模式,应该使用'&',但我没有得到如何做到这一点的示例。

<div ng-controller="tableController as table">
    <row ng-repeat="row in table.rows" row-data="row" row-click="table.updateChart">
    </row>
</div>

.controller('tableController', [function() {
    this.rows = [
        { id: 'foobar', values: ['Chris', 'Kayti'] }
    ];

    this.updateChart = function(row) {
        alert('TODO: update row ' + row.id);  
    };
}])
.directive('row', [function() {
    return {
        restrict: 'E',
        scope: {
            rowData: '=',
            rowClick: '='
        },
        template: '<div class="row" ng-click="rowClick(rowData)">' +
                    '<span ng-repeat="cell in rowData.values">{{ cell }}</span>' +
                  '</div>'
    };
}])

(见http://plnkr.co/edit/ZofcUQcPKQp4zeSNvoOe?p=preview

我正在阅读它,但仍然感到困惑。有人可以给我一个示例,说明如何将这段代码重构为使用'&amp;',好吗?

【问题讨论】:

  • 以下这些答案有什么好运气吗?

标签: angularjs angularjs-directive isolate-scope


【解决方案1】:

从指令的调用者,传递row-click 属性作为函数调用:

<row ng-repeat="row in table.rows" row-data="row" row-click="table.updateChart(row)"></row>

当然改变范围定义:

    scope: {
        rowData: '=',
        rowClick: '&'
    },

还有困难的部分:当调用&amp; 函数时,给它一个对象,其中来自调用站点的每个“正式”参数都是一个属性。我无法更好地表达,对不起:) 对于这种情况:

template: '<div class="row" ng-click="rowClick({row:rowData})">' +
        '<span ng-repeat="cell in rowData.values">{{ cell }}</span>' +
    '</div>'

例如,如果调用是:row-click="table.updateChart(x,y,z)",而您实际上想要这样做:row-click="table.updateChart(1,2,3)",则应将作用域 &amp; 函数调用为:scope.rowClick({x:1, y:2, z:3})

还有一个分叉的 plunk:http://plnkr.co/edit/9xVWXJmMLP8A2OgGTv7R?p=preview

【讨论】:

    【解决方案2】:

    这是一种奇怪的语法,可能没有很好地记录如何传递参数。您需要进行一些更改:-

    在模板集 &amp; 绑定中并将参数作为键的值传递给带有名称的键,例如 rowng-click="rowClick({row: rowData})"&gt;

    return {
            restrict: 'E',
            scope: {
                rowData: '=',
                rowClick: '&'
            },
            template: '<div class="row" ng-click="rowClick({row: rowData})">' +
                        '<span ng-repeat="cell in rowData.values">{{ cell }}</span>' +
                      '</div>'
        };
    

    使用指令时,设置参数的名称,该名称应与指令内部定义的内容内联,即row

    row-click="table.updateChart(row)"
    

    演示

    angular.module('app', []).controller('tableController', [
        function() {
          this.rows = [{
            id: 'foobar',
            values: ['Chris', 'Kayti']
          }];
    
          this.updateChart = function(row) {
            alert('TODO: update row ' + row.id);
          };
        }
      ])
      .directive('row', [
        function() {
          return {
            restrict: 'E',
            scope: {
              rowData: '=',
              rowClick: '&'
            },
            template: '<div class="row" ng-click="rowClick({row:rowData})">' +
              '<span ng-repeat="cell in rowData.values">{{ cell }}</span>' +
              '</div>'
          };
        }
      ])
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <div ng-app="app" ng-controller="tableController as table">
      <row ng-repeat="row in table.rows" row-data="row" row-click="table.updateChart(row)">
      </row>
    </div>

    【讨论】: