将函数传递给指令应该执行的指令

时间:2015-01-06 22:58:39

标签: angularjs angularjs-directive isolate-scope

我对使用'&'和隔离范围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

我正在读它,但仍然感到困惑。有人可以举例说明如何重构此代码以使用'&'吗?

2 个答案:

答案 0 :(得分:1)

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

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

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)"

<强>演示

&#13;
&#13;
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>'
      };
    }
  ])
&#13;
<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>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

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

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

当然要改变范围定义:

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

困难的部分:在调用&函数时,给它一个对象,其中每个&#34;正式&#34;来自调用站点的参数是一个属性。我无法表达更好,抱歉:)对于这种情况:

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)",则应将范围&调用为:scope.rowClick({x:1, y:2, z:3})。< / p>

分叉的插件:http://plnkr.co/edit/9xVWXJmMLP8A2OgGTv7R?p=preview