Angular:寻找有关自定义指令语法的解释

时间:2016-06-14 16:45:43

标签: angularjs angularjs-directive

我复制了watches for changes on form file inputs

的自定义指令
angular.module('customDirective', [])
.directive('ngFileInputChange', function() {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            var onChangeHandler = scope.$eval(attrs.ngFileInputChange);
            element.bind('change', onChangeHandler);
        }
    };
});

然后我在模板中使用它:

<input ng-model="vm.image" ng-file-input-change="vm.base64Test" ...>

这很好用。

但是,这不起作用:

<input ng-model="vm.image" ng-file-input-change="vm.base64Test()" ...>

请注意()末尾的base64Test()。使用泛型ng-click,括号很好,甚至是必需的(如何将参数传递给函数?)但是使用自定义指令时,括号会导致错误。

我对scope.$eval(attrs.ngFileInputChange)实际上在做什么只有模糊的理解,所以也许我可以做些改变?

编辑:

我还应该补充一点,我需要访问一些范围变量。例如,如果我没有必要使用自定义指令,我会在我的控制器中写这样的东西:

vm.base64Test(associatedData){
    console.log(associatedData);    
}

然后:

<input ng-change("vm.base64Test(vm.associatedData)">

但是ng-change不会监视文件输入内容,而自定义指令也不允许参数(事件除外),所以我被卡住了。

2 个答案:

答案 0 :(得分:1)

首先,如果您计划从指令的 API (可以这么说)调用方法,则需要将其识别为回调:

scope: {
    'onChange': '&ngFileInputChange'
}

这只是意味着您在scope.onChange被触发时定义/暴露了一种声明回调的方法。这也意味着您不需要$parse$eval,因为隔离范围可以为您处理。

接下来,你可以像你一直在做的那样触发回调:

element.bind('change', function(evt){
    $scope.$apply(function(){
        var payload = { $data:<whatever-you-pull-from-your-file-change-evt> }
        $scope.onChange(payload)
    }) 
});

有一点需要注意的是,我在$scope.$apply内调用了回调。因为您正在侦听非角度事件(例如onChange),所以您需要通知角度在$digest周期之外发生的更改。

您已经在实际回调中声明了您的指令(可能在视图控制器上定义),您可以将有效负载传递给方法,如下所示:

<input ng-file-input-change="vm.doSomething($data)">

答案 1 :(得分:0)

将函数传递给指令时,通常需要传递函数指针,因此指令稍后可以使用任意参数调用该函数。

在这种情况下,你的指令正在评估函数指针的属性(这就是$ eval正在做的事情),然后将它作为change处理程序绑定到指令所附加的元素。你不需要(或想要)括号。

您的代码目前没有任何问题。我有一个完全相同的指令,效果很棒! (当您调用函数vm.base64Test时,您会在输入中获得standard arguments for a change event。)因此,您可以vm.base64Test为:

function(event) {
  console.log(event);
  // your other code here
  // event.target will give you the input element the code was called on
  // event.target.files will give you an array of the files selected by the user
}