从不调用angularjs指令链接函数

时间:2014-08-14 18:43:56

标签: angularjs angularjs-directive

我创建了这个指令,其意思是定制ngGrid模块,但如果我在带有ng-controller的元素中使用它,它就不会调用链接方法

<div ng-controller="TrainerEditionController">
    <div>Header<br/>
        <div id="trainer-grid"
             class="grid-style"
             data-keyfield="Id"
             data-msgrid="gridOptions"
             data-geturl="@Url.Action("List", "Trainer")"
             data-deleteurl="@Url.Action("Delete","Trainer")">
            <div data-item-template>
                <div data-field="Name" data-editable>
                </div>
                <div data-field="$action">
                    <div class="btn" ng-click="edit()">Edit</div>&nbsp;<div class="btn" ng-click="delete()">Delete</div>
                </div>
            </div>
        </div>
    </div> </div>

这是我的指令定义:

(function(window, $) {
    angular.module('msGrid', ['ngGrid'])
        .directive('msgrid', function() {
            return {
                priority: 3000,
                restrict: 'A',
                link: function($scope, $http, $element) {
                    $scope.__onEditEventHandler = null;
                    $scope.getPageData = function(pageUrl) {
                        $http.post(pageUrl)
                            .success(function(data, status) {
                                if (data.Success === true) {
                                    $scope.myData = data.Result.Data;
                                    $scope.gridOptions.pagingOptions.pages = data.Result.Pages;
                                    $scope.gridOptions.pagingOptions.currentPage = data.Result.CurrentPage;
                                    if (!$scope.$$phase) {
                                        $scope.$apply();
                                    }
                                } else {

                                    //TODO: customize error notification
                                    alert('Error on request, server application said: ' + data.Error + ' status: ' + status);
                                }
                            })
                            .error(function(data, status) {
                                //TODO: customize error notification
                                alert('Error on request, ignoring result status:' + status);
                            });
                    };
                    //set options
                    $scope.gridOptions = {
                        data: 'myData',
                        columnDefs: $element.data('ColumnDefs'),
                        rowHeight: 50,
                        headerRowHeight: 39,
                        enableRowSelection: false,
                        showFooter: true,
                        enablePaging: true,
                        pagingOptions: {
                            pages: [],
                            currentPage: 0
                        }
                    };

                    //load data from server
                    $scope.getPageData($element.data('geturl'));

                    $scope.onEditEventHandler = function(eventHandler) {
                        if (eventHandler === undefined) return;
                        $scope.__onEditEventHandler = eventHandler;
                    };

                    $scope.refresh = function(pageIndex) {
                        var pagingOptions = $scope.gridOptions.pagingOptions;
                        if (pageIndex === undefined)
                            pageIndex = 0;
                        if (pageIndex > pagingOptions.pages.length)
                            pageIndex = pagingOptions.pages.length;
                        $scope.getPageData(pagingOptions.pages[pageIndex]);
                    };

                    $scope.edit = function(row) {
                        var msColumnKeyField = $element.data('keyfield');
                        if (msColumnKeyField == null) return;
                        //get the key value of row
                        var keyValue = row.getProperty(msColumnKeyField);
                        if ($scope.__onEditEventHandler != null)
                            $scope.__onEditEventHandler(keyValue);
                        else {
                            var editUrl = $element.data('editurl');
                            if (editUrl == null) return;
                            window.location.replace(editUrl + '/' + keyValue);
                        }
                    };

                    $scope.delete = function(row) {
                        var msColumnKeyField = $element.data('keyfield');
                        if (msColumnKeyField == null) return;
                        //get the key value of row
                        var keyValue = row.getProperty(msColumnKeyField);
                        //send post to delete
                        var postData = {};
                        postData[msColumnKeyField] = keyValue;
                        $http.post($element.data('deleteurl'), postData)
                            .success(function(data, status) {
                                if (data.Success === true) {
                                    //refresh grid page for new data
                                    var pagingOptions = $scope.gridOptions.pagingOptions;
                                    $scope.getPageData(pagingOptions.pages[pagingOptions.currentPage]);
                                } else {
                                    //TODO: customize error notification
                                    alert(data.Error);
                                }
                            })
                            .error(function(data, status) {
                                //TODO: customize error notification
                                alert('Error on delete, request ignored');
                            });

                    };
                },
                compile: function(tElement, tAttrs) {
                    //load row definitions
                    var requiredTemplate = tElement.find('*[data-item-template]');
                    var myColumnDefs = [];

                    //load columns templates
                    requiredTemplate.children('*[data-field]').each(function() {
                        var self = $(this);
                        var displayName = self.attr('data-displayName');
                        var fieldName = self.attr('data-field');
                        fieldName = (fieldName.indexOf('$') == 0) ? '' : fieldName;
                        var item = {
                            aggLabelFilter: '',
                            cellClass: self.attr('class'),
                            cellFilter: '',
                            enableCellEdit: self.attr('data-editable') === undefined,
                            field: fieldName,
                            displayName: displayName === undefined ? fieldName : displayName,
                            sortable: self.attr('data-sortable') != undefined
                        };
                        var cellTemplate = self.html().trim();
                        if (cellTemplate != '') {
                            cellTemplate = cellTemplate.replace('$value$', '{{row.getProperty(col.field)}}');
                            cellTemplate = cellTemplate.replace('ng-click="delete()"', 'ng-click="delete(row)"');
                            cellTemplate = cellTemplate.replace('ng-click="edit()"', 'ng-click="edit(row)"');
                            item['cellTemplate'] = '<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>' + cellTemplate + '</span></div>';
                        }
                        myColumnDefs.push(item);
                    });
                    tElement.html('<div ng-grid="gridOptions" class="' + tAttrs.class + '"></div>');
                    tElement.data('ColumnDefs', myColumnDefs);
                },
                deleteUrl: ''
            };
        })
        .run([
            '$templateCache', function($templateCache) {
                $templateCache.put('footerTemplate.html',
                    '<div ng-show="showFooter" class="ngFooterPanel" ng-class="{\'ui-widget-content\': jqueryuitheme, \'ui-corner-bottom\':jqueryuitheme}" ng-style="footerStyle()">' +
                    '<div style="text-align: right"><ul class="pagination">' +
                    '<li ng-repeat="page in pagingOptions.pages"><div class="btn" ng-class="pagingOptions.currentPage==$index ? \'disabled\' :\'\'" ng-click="getPageData(page)">{{$index+1}}</div></li>' +
                    '</ul></div>' +
                    '</div>');
            }
        ]);
}(window, jQuery));

如果指令在没有ng-controller的元素中使用,则可以正常工作

1 个答案:

答案 0 :(得分:0)

您的指令功能无效。

当你有编译功能时,你的链接功能实际上是postLink。 还要检查链接函数的参数。

来自AngularJS $compile API

var myModule = angular.module(...);

  myModule.directive('directiveName', function factory(injectables) {
    var directiveDefinitionObject = {
      priority: 0,
      template: '<div></div>', // or // function(tElement, tAttrs) { ... },
      // or
      // templateUrl: 'directive.html', // or // function(tElement, tAttrs) { ... },
      transclude: false,
      restrict: 'A',
      scope: false,
      controller: function($scope, $element, $attrs, $transclude, otherInjectables) { ... },
      controllerAs: 'stringAlias',
      require: 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'],
      compile: function compile(tElement, tAttrs, transclude) {
        return {
          pre: function preLink(scope, iElement, iAttrs, controller) { ... },
          post: function postLink(scope, iElement, iAttrs, controller) { ... }
        }
        // or
        // return function postLink( ... ) { ... }
      },
      // or
      // link: {
      //  pre: function preLink(scope, iElement, iAttrs, controller) { ... },
      //  post: function postLink(scope, iElement, iAttrs, controller) { ... }
      // }
      // or
      // link: function postLink( ... ) { ... }
    };
    return directiveDefinitionObject;
  });