控制器参数在我的指令链接功能中未定义

时间:2014-05-24 15:32:30

标签: javascript angularjs

我正在尝试做一些非常简单的事情,使用链接函数的controller参数作为我的指令,但是它被传递为'undefined'。谁能告诉我我错过了什么?

HTML:

    <div ng-app="myApp">
        <div ng-controller="SampleCtrl" my-form >
            <p> Click count: {{ count }} </p>               
        </div>  
    </div>

Javascript:

myApp.controller('SampleCtrl', function($scope){    
    $scope.count = 0;

    this.init = function(val) {
        $scope.count = val;
    }   
});


myApp.directive('myForm', function() {    
    var linkFn = function(scope, elem, attrs, ctrl) {

        ctrl.init(17); //Error here.  ctrl is undefined

        elem.bind('click', function() {
            scope.$apply(function(){                
                scope.count++;
            });
        });     
    };

    return linkFn;
});

3 个答案:

答案 0 :(得分:2)

Dan正确地评论了对已接受答案的评论

  

为什么世界上的指令必须有任何直接的参考   到一个特定的控制器?不是他们应该是好的   便携式?

您无需引用控制器来利用指令中的ctrl参数。

相反,您可以使用require: 'ngModel'

由于模型将在ng-controller范围值内定义,因此无需对控制器名称进行硬编码即可创建指向控制器的链接。

这是一个基于指令的示例,如果输入文件太大,我用它来将表单设置为无效。

myApp.directive('maxFileSize', function () {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, element, attrs, ctrl) {
            var maxSize = Number(attrs.maxFileSize);

            var sizeHandler = function () {
                if (element.get(0).files.length) {
                    var fileSize = element.get(0).files[0].size; // in bytes
                    if (fileSize > maxSize) {
                        //console.log('file size is more than ' + maxSize + ' bytes!');

                        ctrl.$setValidity("fileSize", false);
                    } else {
                        ctrl.$setValidity("fileSize", true);
                    }
                }
            };

            element.bind('change', sizeHandler);
        }
    };
});

答案 1 :(得分:1)

您可以像我在Plunk中所做的一样,而不是尝试使用控制器吗?

答案 2 :(得分:0)

似乎我的指令必须使用指令定义对象来返回链接函数并包含对Controller的引用作为ddo的'controller'参数,如下所示:

myApp.directive('myForm', function() {

    var linkFn = function(scope, elem, attrs, ctrl) {

        ctrl.init("17"); //This now works, due to my return below


        elem.bind('click', function() {
            scope.$apply(function(){                
                scope.count++;
            });
        });     
    };

    return {
        controller: 'SampleCtrl',
        link:linkFn};
});