在AngularJs指令中,如何调用其指令元素属性中包含的控制器函数?

时间:2014-04-03 02:51:51

标签: angularjs angularjs-directive angularjs-scope angularjs-controller

我试图在控制器中调用一个函数,它是自定义角度指令的一部分,以下是代码,

方法1:(不起作用:控制器的功能不会写入控制台)

HTML:

<div ng-app="MyApp">
    <my-directive callback-fn="ctrlFn(arg1)"></my-directive>
</div>

JS:

var app = angular.module('MyApp', []);

app.directive('myDirective', function() {
    return {
        restrict: 'E',
        scope: { someCtrlFn: '&callbackFn' },
        link: function(scope, element, attrs) {
            scope.someCtrlFn({arg1: 22});
        },
        controller: function ($scope) {
            $scope.ctrlFn = function(test) {
                console.log(test);
            }
        }
    }
});

当我从中移除指令的控制器并创建一个新的控制器时,它可以工作,

方法2:(Works:Controller的函数写入控制台)

HTML:

<div ng-app="MyApp" ng-controller="Ctrl">
    <my-directive callback-fn="ctrlFn(arg1)"></my-directive>
</div>

JS:

var app = angular.module('MyApp', []);

app.directive('myDirective', function() {
    return {
        restrict: 'E',
        scope: { someCtrlFn: '&callbackFn' },
        link: function(scope, element, attrs) {
            scope.someCtrlFn({arg1: 22});
        }
    }
});

app.controller('Ctrl', function ($scope) {
    $scope.ctrlFn = function(test) {
        console.log(test);
    }
});

我想知道如何在方法1 中获得方法2 的行为,即能够从指令的属性调用指令的控制器函数。

非常感谢任何帮助,谢谢!

2 个答案:

答案 0 :(得分:1)

方法1 中,您将创建一个隔离范围并定义范围值someCtrlFn,该范围值从使用您的指令的父范围接收函数。要使用的函数由属性callbackFn指定。

指令与这些范围项一起使用的方式是,它们应该从使用指令时处于活动状态的父范围内的事物中分配。因此,如果您的方法2 中有控制器Ctrl,那么在该范围内使用该指令,您的指令会尝试将您在属性中定义的内容与可用内容相匹配在Ctrl的范围内。

所以,在你的第一个例子中,它正在父范围内寻找一个名为ctrlFn的函数,但没有一个。它不会试图在指令的控制器上寻找它。这就是方法2 的工作原理,因为父范围定义了ctrlFn,并且该指令能够正确地调用该表达式。

这些范围属性的目的是允许指令绑定到父范围上的值或函数以促进通信。例如,要给出它将显示或修改的指令数据,或者允许父级定义一个函数,该指令可以在事件期间调用回调或者你有什么。父作用域不能移入指令的作用域并强制指令的作用域使用自己定义的项(除非你设置它,所以你的指令使用默认值或函数,如果省略属性或其他)。

它们未被使用,因此指令可以在其内部使用的范围内定义事物。如果这些内容属于指令的内部,您可以在link期间或适当的时候将它们添加到范围中。

你的意思是这样吗?

var app = angular.module('MyApp', []);

app.directive('myDirective', function() {
    return {
        restrict: 'E',
        scope: { },
        link: function(scope, element, attrs) {
            // defines ctrlFn that can be used later by this directive's template or controller
            scope.ctrlFn = function(test) {
                console.log(test);
            }

            // immediately invokes ctrlFn to log a message, just here to illustrate
            scope.ctrlFn('Hello World!');
        }
    }
});

答案 1 :(得分:0)

在指令控制器

中使用$ rootScope而不是$ scope实现了它

<强> HTML:

<div ng-app="MyApp">
    <my-directive callback-fn="ctrlFn(arg1)"></my-directive>
</div>

<强> JS:

<script>
var app = angular.module('MyApp', []);

app.directive('myDirective', function($rootScope) {
    return {
        restrict: 'E',
        scope: { someCtrlFn: '&callbackFn' },
        link: function(scope, element, attrs) {
            scope.someCtrlFn({arg1: 22});
        },
        controller: function ($scope) {
            $rootScope.ctrlFn = function(test) {
                console.log(test);
            }
        }
    }
});
</script>