【问题标题】:AngularJS use a directive to prevent other directives to executeAngularJS 使用一个指令来阻止其他指令执行
【发布时间】:2014-04-14 16:27:01
【问题描述】:

我的 Angular 应用程序中的某些操作需要用户注册。如果用户未注册,我们希望显示“注册模式”并阻止原始操作。

可以通过 ng-click 或任何其他“点击绑定”指令(例如“modal-toggle”指令)触发这些操作。

所以我找到了这个解决方案:https://stackoverflow.com/a/16211108/2719044

这很酷,但仅适用于 ng-click。

我首先想让指令的“终端”属性动态化,但没能做到。

所以想法是将“终端”设置为 true 并手动阻止指令中的默认点击操作。

这是我的 DOM

<!-- This can work with terminal:true and scope.$eval(attrs.ngClick) (see example above) -->
<div user-needed ng-click="myAction()">Do it !</div> 

<!-- This doesn't work. I can't manage to prevent the modal-toggle to be executed -->
<div user-needed modal-toggle="my-modal-id-yey">Show yourself modal !</div> 

还有我的指令(不起作用...)

// First try (with terminal:true)
app.directive('userNeeded', function() {
    return {
        priority: -100,
        terminal: true,
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.bind('click', function(e) {
                if(isRegistered()) {
                    // Here we do the action like scope.$eval or something
                }
            });
        }
    };
});

// Second try (with stopPropagation)
app.directive('userNeeded', function() {
    return {
        priority: -100
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.bind('click', function(e) {
                if(!isRegistered()) {
                    e.stopPropagation();
                }
            });
        }
    };
});

...这就是我在这里的原因。有什么想法吗?

非常感谢。

【问题讨论】:

  • 你应该看看 angular-app 项目,它以我从现在发现的最佳方式处理身份验证:github.com/angular-app/angular-app(参见安全模块)
  • 这似乎不能解决我的问题。我不需要一般的身份验证功能。
  • 不是。如果您想限制访问,您可以逐个路由选择路由(定义新路由时请参阅resolve 节点)。这个限制可以是普通用户/管理员用户。但你不必采用他们的模式;)这只是一个很好的例子。
  • 另一件事,您希望通过“onclick”事件限制页面的方式并不安全。您必须保护的不是链接,而是“路线”
  • 我所有的动作都不是路由。有时它只是显示或不显示模态。是的,它不安全,但就我而言,这并不重要。模态中的表单已经是安全的,但显示模态的动作并不需要。如果用户已通过身份验证,我只想通过指令捕获点击并进行测试。如果不是,我不显示模式并重定向到登录表单。不知道我是否清楚。

标签: angularjs terminal directive stoppropagation


【解决方案1】:

你非常接近。您需要停止立即传播,而不是 stopPropagation。两者的区别由@Dave总结在this StackOverflow answer中:

stopPropagation 将阻止任何 parent 处理程序 在stopImmediatePropagation 执行时会执行相同的操作但是 也阻止其他处理程序执行。

所以要修复代码,我们所要做的就是换掉那个方法,然后瞧:

app.directive('userNeeded', function() {
    return {
        priority: -100
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.bind('click', function(e) {
                if(!isRegistered()) {
                    e.stopImmediatePropagation();
                }
            });
        }
    };
});

这是工作代码的example Plunker。在示例中,我稍微修改了指令以允许通过将值直接传递给element.bind 函数来指定特定事件(例如user-needed="submit");但是,它默认为“点击”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-02
    • 2014-03-08
    • 2015-06-24
    • 1970-01-01
    • 1970-01-01
    • 2020-06-24
    • 1970-01-01
    相关资源
    最近更新 更多