包含为指令的通用功能

时间:2014-04-18 23:05:39

标签: javascript angularjs angularjs-directive angularjs-scope

我正在尝试编写一个指令,它将在我的应用程序中的任意位置对任意数据进行排序。让我们说我有以下代码(基于实际的实际代码,排序函数和一些简单的复杂性)

angular.module('test', []);
angular.module('test').controller('wrapperController',['$scope', function(scope){
  scope.data = {}
  scope.data.rows = [{name: 'foo'}, {name: 'bar'}, {name: 'bazz'}]
  scope.data.columns = [{name: 'Name', sortBy: 'name'}]
}]);
angular.module('test').directive('grid', [function(){
  return {
    restrict: 'A',
    templateUrl: 'grid.html',
    scope: {
      grid: '='
    }
  }
}]);
angular.module('test').directive('sortable', [function(){
  return {
    restrict: 'A',
    scope: {
      sortableCollection: '=',
      sortableKey: '&'
    },
    compile: function(el, at, transclude){
      if(at['ng-click']){
        el.attr('ng-click', el.attr('ng-click')+';sortFunction()')
      }else{
        el.attr('ng-click', 'sortFunction();')
      }
      return(function(scope, element, attrs){
        scope.sortableKey = scope.sortableKey();
        scope.sortFunction = function(){
          alert(" I AM IN UR FUCNTION SORTING UR D00dZ!!1");
        }
      });
    }
  }
}]);

以下html:

<body ng-app='test'>
    <div ng-controller='wrapperController'>
      <div grid='data'></grid>
    </div>
  </body>

和(在grid.html中):

    <div>
  <table>
    <thead>
      <tr>
        <td ng-repeat='column in grid.columns'>
            <div sortable sortable-collection='grid' sortable-key='column.sortBy'>{{column.name}}</div>
        </td>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat='row in grid.rows'>
        <td ng-repeat='cell in grid.columns'>
          {{row.name}}
        </td>
      </tr>
    </tbody>
  </table>
</div>

检查HTML显示ng-click正确填充,但是当单击标题时,函数永远不会触发。这是为什么?有没有办法来获得这种行为?

plunr:http://plnkr.co/edit/aXjMqhZxI7ME8wQJOLpA?p=preview

2 个答案:

答案 0 :(得分:3)

简单地添加属性并不会使角度运行该指令。当angular启动应用程序时,它会扫描DOM以获取指令。然后它调用它们的编译函数。因此,当您在该功能中添加ng-click时,为时已晚。

在指令中添加ng-click无论如何都没有意义。您想为click事件添加事件侦听器。

link: (function(scope, element, attrs){
    scope.sortableKey = scope.sortableKey();
    element.on('click',  function(){
      alert(" I AM IN UR FUCNTION SORTING UR D00dZ!!1");
      // call $scope.apply(); after you have changed the model
    });

答案 1 :(得分:1)

您的网格指令可以在其范围内创建control object

link: function(scope, element, attrs) {
  scope.sorter = {};
}

并将其传递给sortable指令:

<div sortable sort-control='sorter'...></div>

然后,sortable指令将排序函数添加到控件对象:

scope: {
  ....
  sortControl: '='
},
link: function(scope, element, attr) {
  if (scope.sortControl) {
    scope.sortControl = {
      sortFunction: function() {
        alert(" I AM IN UR FUCNTION SORTING UR D00dZ!!1");
      }
    };
  } 
}

最后,回到网格模板中,我们可以将排序函数作为控件对象的属性来访问:

<div sortable ng-click='sorter.sortFunction()' sort-control='sorter'...></div>

这是一个有效的演示:http://plnkr.co/edit/iYkVbh2wGfCWBWA0SX3M?p=preview