AngularJS传递函数与动态参数指令

时间:2015-02-10 11:17:06

标签: angularjs angularjs-directive parameter-passing

TL; DR版本:我正在尝试编写一个指令来显示表中的各种对象,并在表行的末尾添加一个编辑/删除按钮。

示例实体将是ProjectType,因此:

项目type.controller.js

    // determines which attributes we want to show in the table
    $scope.attr = [
        'computerName',
        'shortName',
        'longName'
    ];

    // puts the current projectType object to the form
    $scope.edit = function(projectType) {
        $scope.projectType = projectType;
        $scope.computerName = projectType.computerName;
        $scope.isEdit = true;
    };

    // shows a delete modal window
    $scope.deleteConfirm = function (projectType) {
        Modal.confirm.deleteModal('Project type', projectType.computerName, function () {
            Message.createMessage('project-type.message.delete.success', { projectType: projectType.computerName }, { type: 'warning', timeout: 4000 });

            $scope.remove(projectType);
        })();
    };

项目type.html

    <!-- show table with directive -->
    <entity-table object="projectTypes" entity="'project-type'" attr="attr"></entity-table>

    <!-- show table without directive -->          
    <table class="table table-responsive">
        <thead>
        <tr>
            <th>{{ 'project-type.create.label.computerName' | translate }}</th>
            <th>{{ 'project-type.create.label.shortName' | translate }}</th>
            <th>{{ 'project-type.create.label.longName' | translate }}</th>
            <th>{{ 'common.operations' | translate }}</th>
        </tr>
        </thead>

        <tbody>
        <tr ng-repeat="projectType in projectTypes">
            <td><strong>{{ projectType.computerName }}</strong></td>
            <td>{{ projectType.shortName }}</td>
            <td>{{ projectType.longName }}</td>
            <td>
                <a ng-click="edit(projectType)" class="pencil"><span class="glyphicon glyphicon-pencil"></span></a>
                <a ng-click="deleteConfirm(projectType)" class="trash"><span class="glyphicon glyphicon-trash"></span></a>
            </td>
        </tr>
        </tbody>
    </table>

实体table.directive.js

angular.module('unioffice-centralApp')
.directive('entityTable', function () {
    return {
        restrict: 'E',
        replace: true,
        transclude : true,
        templateUrl: '/components/directives/entity-table/entity-table.html',
        scope: {
            object: '=',
            entity: '=',
            attr: '='
        },
        link: function (scope, element, attrs, controllers, transclude) {
            console.log(scope);
        }
    };
});

实体table.html

<div>
<table class="table table-responsive">
    <thead>
    <tr>
        <th ng-repeat="att in attr">{{ (entity + ".table.label." + att) | translate }}</th>
        <th ng-repeat-end translate>common.operations</th>
    </tr>
    </thead>

    <tbody>
        <tr ng-repeat="obj in object">
            <td ng-repeat="att in attr">{{ obj[att] }}</td>
            <td ng-repeat-end>
                <a ng-click="edit(obj)" class="pencil"><span class="glyphicon glyphicon-pencil"></span></a>
                <a ng-click="deleteConfirm(obj)" class="trash"><span class="glyphicon glyphicon-trash"></span></a>
            </td>
        </tr>
    </tbody>
</table>

(在entity-table.html的末尾有一个/ div,stackoverflow似乎要杀了它)

所以问题是:如何将edit()和deleteConfirm()函数传递给指令以使它们起作用?

在这张图片中你可以看到两张表是相同的,但是第一张中的按钮显然不会做任何事情:(我也知道第二列有粗体的第一列,没关系,那不是现在这一点)screenshot

1 个答案:

答案 0 :(得分:1)

将函数从控制器传递/绑定到指令的方式与绑定对象=或字符串@的方式相同,区别在于它在指令中的引用方式

将函数作为指令的属性传递,如下所示。

<entity-table object="projectTypes" entity="'project-type'" on-delete="deleteConfirm" on-edit="edit" attr="attr"></entity-table>

在你的指令中这样做..

angular.module('unioffice-centralApp')
.directive('entityTable', function () {
    return {
        restrict: 'E',
        replace: true,
        transclude : true,
        templateUrl: '/components/directives/entity-table/entity-table.html',
        scope: {
            object: '=',
            entity: '=',
            attr: '=',
            onDelete: '&', // function referencing
            onEdit: '&' // function referencing
        },
        link: function (scope, element, attrs, controllers, transclude) {
            scope.deleteFn = function (obj) {
                scope.onDelete()(obj); // this invokes the deleteConfirm function in the controller
            }

            scope.editFn = function (obj) {
                scope.onEdit()(obj); // this invokes the deleteConfirm function in the controller
            }
        }
    };
});

在你的控制器......

$scope.edit = function(projectType) {
    $scope.projectType = projectType;
    $scope.computerName = projectType.computerName;
    $scope.isEdit = true;
};

// shows a delete modal window
$scope.deleteConfirm = function (projectType) {
    Modal.confirm.deleteModal('Project type', projectType.computerName, function () {
        Message.createMessage('project-type.message.delete.success', { projectType: projectType.computerName }, { type: 'warning', timeout: 4000 });

        $scope.remove(projectType);
    })();
};

<强> PLUNKR