当前位置: 首页 > 知识库问答 >
问题:

从AngularJS中没有隔离范围的指令调用控制器函数

子车高歌
2023-03-14

如果不使用隔离作用域,我似乎找不到从指令中调用父作用域上的函数的方法。我知道如果我使用隔离作用域,我可以使用“

<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不再针对父作用域执行,而是在隔离作用域中执行(因为在任何指令上使用隔离作用域会导致该元素上的所有指令都使用隔离作用域)。这里是上述示例的JSFIDLE,其中ng hide不起作用。(请注意,在此小提琴中,当您在输入框中键入“是”时,按钮应隐藏。)

另一种选择是不使用隔离的作用域,这实际上是我在这里真正想要的,因为不需要隔离这个指令的作用域。我唯一的问题是,如果不在独立作用域上传递方法,如何在父作用域上调用该方法?

这是一个jsfiddle,我没有使用孤立的范围和ng-隐藏工作正常,但是,当然,调用确认动作()不工作,我不知道如何使它工作。

请注意,我真正想要的答案是如何在不使用隔离作用域的情况下调用外部作用域上的函数。我不想让这个确认对话框以另一种方式工作,因为这个问题的重点是找出如何调用外部作用域,并且仍然能够让其他指令针对父作用域工作。

或者,如果其他指令仍然对父作用域起作用,我很想听到使用隔离作用域的解决方案,但我认为这是不可能的。

共有3个答案

邹斌
2023-03-14

在父作用域上显式调用隐藏按钮。

小提琴是这样的: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>
宿丰
2023-03-14

您希望使用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设置属性有一个问题,但当您遇到它时,我会让您过桥。

云航
2023-03-14

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

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

或者更好的方法是,只需使用$apply,它将$eval()评估其反对作用域的论点:

scope.$apply(attrs.confirmAction);

不停摆弄

 类似资料:
  • 问题内容: 我似乎找不到不使用隔离范围从指令内调用父范围内的函数的方法。我知道,如果我使用隔离作用域,则可以在隔离作用域中使用“&”来访问父作用域上的函数,但是在不必要时使用隔离作用域会产生后果。考虑以下HTML: 在这个简单的示例中,我想显示一个JavaScript确认对话框,并且仅当他们在确认对话框中单击“确定”时才调用doIt()。使用隔离范围很简单。该指令如下所示: 但是问题是,因为我使用

  • 问题内容: 我想编写带有隔离范围的指令,但也想使该范围可用于父范围的控制器。我找到了这个解决方案: 参见柱塞。 我觉得这有点丑陋,因为它涉及用HTML编写属性,而在控制器的代码中,您无法确定范围属性的来源。有一个更好的方法吗? 编辑: 此外,似乎在运行控制器“ Main”时$ scope.popup甚至不可用。指令的链接功能尚未执行? 问题答案: 为了保持适当的关注点分离,您不应该混合作用域。更不

  • 那么,的目的是什么?不能访问通过传递的所有属性。为什么一个max的访问值不能作为而不是 为什么要像那样分配回来? 谢了。

  • 问题内容: 我想在没有自己的模板的AngularJS中创建可重用的指令。我也想为该指令设置隔离范围。我的方法的最佳做法是什么?为什么我的示例不符合我的预期? 我希望可以分别从指令中编辑obj1和obj2。 HTML: JS: PLUNKR:http://plnkr.co/edit/Dw8IiFVSOZGjSTFGRMzZ 问题答案: 您的代码现在的工作方式是,每个指令的内容都绑定到父作用域,而不是

  • 问题内容: 请在这里查看示例 角需要,,以在所述分离的范围对象从父范围访问它来限定。 在这里使用 那么,目的是什么?无法访问通过传递的所有属性。为什么不能将max的一个访问值代替 为什么要分配回来像? 由于此应用程序是由Angular作者编写的,因此我希望有一个理由。 谢谢。 问题答案: attrs的目的是什么? 在与指令相同的元素上定义的属性有几个用途: 它们是将信息传递到使用隔离范围的指令的唯

  • 问题内容: 我首先尝试使用AngularJS自定义指令。 我在指令的链接功能中使用(或理解…)隔离范围时遇到麻烦。 这是我应用程序这部分的代码: view.html 是在viewCtrl范围内发布的变量,其中包含请求的xml字符串。 rawData.js raw-data.html 我不明白为什么弹出模式时会显示ID正确,但是当我尝试使用它时,其值是不确定的。 也许我对隔离的范围值(和)错了。 感