search

Home  >  Q&A  >  body text

javascript - 关于Angular Directive 绑定策略中的 “&” 的问题

Angular的Directive中,&表示提供一个表达式,可以在父scope上下文中执行。

举个例子:

// HTML
<tr ng-repeat="hwInfo in hwInfoList">
    <td>
        <button class="btn btn-sm btn-primary ng-upload" file="hwInfo.AttachmentFile" callback="uploadAttach(hwInfo)">
            <span class="fa fa-paperclip"></span>
        </button>
    </td>
</tr>

// Javascript
app.directive('ng-upload', [
    function () {
        function link($scope, element, attrs) {
            // ...
            
            $scope.callback('123');
        }

        return {
            restrict: 'C',
            scope: {
                uploader: '=?',     // 入参,上传文件地址
                file: '=?',         // 入参,已有文件
                viewOnly: '@?',     // 入参,只需要查看
                callback: '&?'      // 入参,回调数据
            },
            link: link
        };
    }
]);

app.controller('myController', function ($scope) {
    $scope.uploadAttach = function (model) {
        return function (file) {
            if (file) {
                model.fileID = file.ID;
            } else {
                model.fileID = '';
            }
        };
    };
});

上面的代码是我理想的情况,实际情况是并没有按照设想的工作。

我想问下,有没有办法可以在传给指令的回调函数中传入自定义的参数?

----------------------------------分割线-------------------------------------

经过对angularJS的指令API解读以及综合各位朋友的回答,我总结出了一种既能在外面传参数,也能在指令内部传参数的方法。上代码:

// HTML
<tr ng-repeat="hwInfo in hwInfoList">
    <td>
        <button class="btn btn-sm btn-primary app-upload" file="hwInfo.AttachmentFile" callback="uploadAttach(hwInfo, file)">
            <span class="fa fa-paperclip"></span>
        </button>
    </td>
</tr>

// Javascript
app.controller('myCtrl', [
    '$scope',
    function ($scope, $locale) {
        $scope.hwInfoList = [
            {
                caption  : 'Hello',
                file : {ID : "ABC"}
            },
            {
                caption  : 'World',
                file : {ID : "BCD"}
            }
        ];
        $scope.uploadAttach = function (hwInfo, file) {
            console.log(arguments);
            if (file) {
                hwInfo.fileID = file.ID;
            } else {
                hwInfo.fileID = '';
            }
        };
    }
]);

app.directive('appUpload', [    //你这里有问题,需要用驼峰法
    function () {
        function link(scope, element, attrs) {
            element.on('click', function () {
                scope.callback({ file: { ID: 12 } });
            });
        }
        return {
            restrict: 'A',
            scope: {
                uploader: '=',     // 入参,上传文件地址
                file: '=',         // 入参,已有文件
                viewOnly: '@',     // 入参,只需要查看
                callback: '&'      // 入参,回调数据  /* 2:关联 */
            },
            link: link
        };
    }
]);

callback="uploadAttach(hwInfo, file)" 这句话声明传递给回调函数的两个参数,其中hwInfo来自外部ng-repeat="hwInfo in hwInfoList",file从指令内部传递scope.callback({ file: { ID: 12 } })

这就达到了我想要的效果了

黄舟黄舟2787 days ago801

reply all(3)I'll reply

  • 天蓬老师

    天蓬老师2017-04-11 13:34:49

    定义:
    callback : “& uploadAttach(hwInfo)” 这里是伪代码,只是为了表明定义和关联方法

    传参:
    callback({hwInfo:'123'})

    之前手机回答,不太好编辑符号,这样就可以调用。

    因为你之前调用的是 hwInfo in hwInfoList,hwInfo 会引起变量覆盖。我把传参改为 arg,重新写了个demo,,你可以运行一次啊,就能看到 callback({hwInfo:'123'}) 这种方式是对的。

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <script src="http://cdn.static.runoob.com/libs/angular.js/1.4.6/angular.min.js"></script>
    </head>
    <body ng-app="myApp" ng-controller="myController">
    
    <table>
    <tr ng-repeat="hwInfo in hwInfoList">
        <td>
            <button class="btn btn-sm btn-primary app-upload" file="hwInfo.AttachmentFile" callback="uploadAttach(hwInfo)"><!--  1:定义:callback : “& uploadAttach(arg)” -->
                <span class="fa fa-paperclip">{{ hwInfo.hwInfoCaption }}</span>
            </button>
        </td>
    </tr>
    </table>
    
    <script>
    var app = angular.module('myApp', []);
    app.controller('myController', function ($scope) {
        $scope.hwInfoList = [
            {
                AttachmentFile : 'jpg',
                hwInfoCaption  : 'Hello',
                file : {ID : "ABC"}
            },
            {
                AttachmentFile : 'jpg',
                hwInfoCaption  : 'World',
                file : {ID : "BCD"}
            }
        ];
        $scope.uploadAttach = function(hwInfo) {
            console.log(hwInfo.file.ID);
            /*
                3:调用,方式一
                    使用 scope.callback({hwInfo:{file: {ID : window.fileIndex} } }); 调用:
                    返回:    100001
                            100002
            */
            /*
                3:调用,方式二,
                    使用 scope.callback(); 调用:
                    返回:    ABC
                            BCD
            */
            
            return function (file) {
                if (file) {
                    model.fileID = file.ID;
                } else {
                    model.fileID = '';
                }
            };
        };
    });
    app.directive('appUpload', [    //你这里有问题,需要用驼峰法
        function () {
            function link(scope, element, attrs) {
                window.fileIndex = ++window.fileIndex || 100001;
                scope.callback({hwInfo:{file: {ID : window.fileIndex} } }); /* 3:调用,方式一,传参方式 */
                //scope.callback(); /* 3:调用,方式二,不指定hwInfo,因为重名,它会使用 hwInfo in hwInfoList 的 hwInfo */
            }
            return {
                restrict: 'C',
                scope: {
                    uploader: '=',     // 入参,上传文件地址
                    file: '=',         // 入参,已有文件
                    viewOnly: '@',     // 入参,只需要查看
                    callback: '&'      // 入参,回调数据  /* 2:关联 */
                },
                link: link
            };
        }
    ]);
    
    </script>
    </body>
    </html>

    reply
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-11 13:34:49

    尽量不要用class做指令,根据你的代码,我改了一下,你看看能不能work:

    // HTML
    <tr ng-repeat="hwInfo in hwInfoList">
        <td>
            <button ng-upload class="btn btn-sm btn-primary" file="hwInfo.AttachmentFile" callback="uploadAttach" hwInfo="hwInfo">
                <span class="fa fa-paperclip"></span>
            </button>
        </td>
    </tr>
    
    // Javascript
    app.directive('ng-upload', [
        function () {
            function link($scope, element, attrs) {
                // ...
                
                $scope.callback($scope.hwInfo);
            }
    
            return {
                restrict: 'A',
                scope: {
                    uploader: '=?',     // 入参,上传文件地址
                    file: '=?',         // 入参,已有文件
                    viewOnly: '@?',     // 入参,只需要查看
                    callback: '&?',      // 入参,回调数据
                    hwInfo: '='
                },
                link: link
            };
        }
    ]);
    
    app.controller('myController', function ($scope) {
        $scope.uploadAttach = function (model) {
            return function (file) {
                if (file) {
                    model.fileID = file.ID;
                } else {
                    model.fileID = '';
                }
            };
        };
    });

    reply
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-11 13:34:49

    只知道=,@,&是用来绑定父级作用域的属性的,callback用&绑定后和父级作用域的就不是一个了,传参的话直接传肯定不行,放在$attr中是比较好的办法
    这个callback放在指令中执行,为什么要从父级controller传过来呢,直接定义在指令中不是更好?

    reply
    0
  • Cancelreply