在AngularJS中调用一个没有独立范围的指令的控制器函数

我似乎无法找到一种方法来从指令中调用父范围的函数,而不使用隔离范围。 我知道,如果我使用独立作用域,我可以在孤立作用域中使用“&”来访问父作用域的作用,但在不需要时使用独立作用域会产生后果。 考虑下面的HTML:

<button ng-hide="hideButton()" confirm="Are you sure?" confirm-action="doIt()">Do It</button>

在这个简单的例子中,我想要显示一个JavaScript确认对话框,并且只有在确认对话框中点击“确定”才调用doIt()。 使用隔离范围很简单。 该指令看起来像这样:

.directive('confirm', function () {
    return {
        restrict: 'A',
        scope: {
            confirm: '@',
            confirmAction: '&'
        },
        link: function (scope, element, attrs) {
            element.bind('click', function (e) {
                if (confirm(scope.confirm)) {
                    scope.confirmAction();
                }
            });
        }
    };
})

但问题是,因为我使用了隔离作用域,上面示例中的ng-hide不再针对父作用域执行 ,而是在独立作用域中执行(因为在任何指令上使用隔离范围都会导致该元素上的所有指令使用隔离的范围)。 上面的示例中,ng-hide不起作用,这是一个jsFiddle。 (请注意,在此小提琴中,当您在输入框中键入“是”时,该按钮应该隐藏。)

另一种选择是不使用隔离范围 ,这实际上是我真正想要的,因为不需要隔离这个指令的范围。 我唯一的问题是, 如果我不通过隔离作用域如何在父作用域上调用方法

这里是一个jsfiddle,我没有使用独立的范围,并且ng-hide工作正常,但是,当然,对confirmAction()的调用不起作用,我不知道如何使它工作。

请注意,我真正想要的答案是如何调用外部范围的函数而不使用隔离的范围。 而且我不希望以另一种方式进行确认对话框工作,因为这个问题的关键是要弄清楚如何调用外部作用域,并且仍然可以使其他指令对父级作用域起作用。

另外,如果其他指令仍然会对父范围起作用,我会很乐意听到使用隔离范围的解决方案 ,但我认为这是不可能的。


由于该指令只调用一个函数(而不是试图在属性上设置一个值),因此可以使用$ eval而不是$ parse(使用非隔离范围):

scope.$apply(function() {
    scope.$eval(attrs.confirmAction);
});

或者更好的,只需使用$ apply,这将使$ eval()使用它的参数来抵抗范围:

scope.$apply(attrs.confirmAction);

小提琴


你想在AngularJS中使用$ parse服务。

因此,对于你的例子:

.directive('confirm', function ($parse) {
    return {
        restrict: 'A',

        // Child scope, not isolated
        scope : true,
        link: function (scope, element, attrs) {
            element.bind('click', function (e) {
                if (confirm(attrs.confirm)) {
                    scope.$apply(function(){

                        // $parse returns a getter function to be 
                        // executed against an object
                        var fn = $parse(attrs.confirmAction);

                        // In our case, we want to execute the statement in 
                        // confirmAction i.e. 'doIt()' against the scope 
                        // which this directive is bound to, because the 
                        // scope is a child scope, not an isolated scope. 
                        // The prototypical inheritance of scopes will mean 
                        // that it will eventually find a 'doIt' function 
                        // bound against a parent's scope.
                        fn(scope, {$event : e});
                    });
                }
            });
        }
    };
});

使用$ parse设置一个属性有一个问题,但当你到达它时,我会让你穿过那座桥。


在父范围上显式调用hideButton

这是小提琴:http://jsfiddle.net/pXej2/5/

这里是更新的HTML:

<div ng-app="myModule" ng-controller="myController">
    <input ng-model="showIt"></input>
    <button ng-hide="$parent.hideButton()" confirm="Are you sure?" confirm-action="doIt()">Do It</button>
</div>
链接地址: http://www.djcxy.com/p/77811.html

上一篇: Call a controller function from a directive without isolated scope in AngularJS

下一篇: Update parent scope variable in angular