在 AngularJS 指令中高级操作 DOM [英] Advanced manipulating DOM in AngularJS directive

查看:28
本文介绍了在 AngularJS 指令中高级操作 DOM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在解决 AngularJS 应用程序中的权限...我想使用自定义指令来解决用户可以通过其角色看到的内容.这只是客户端设计.如果用户在页面上输入了他没有访问过的内容,服务器将针对来自该页面的所有数据请求返回 403.我的实际解决方案如下所示:

  • <a href="#/{{menuItem.url}}"><div class="label"><span class="icon"><span class="title">{{menuItem.title}}</span></span>
  • </a>

    .directive('restrictAccess', function() {返回 {限制:'EA',优先级:100000,范围: {限制访问:=限制访问"},控制器:['$scope', '$element', function($scope, $element) {var accessDenied = true;var userRole = App.LoggedUser.userRole;var 属性 = $scope.restrictAccess.split(" ");for (var i in attributes) {如果(用户角色 == 属性 [i]){accessDenied = false;}}如果(访问被拒绝){$element.remove();}}]};})

    问题很多...

    由 ng-include 呈现的小部件的控制器比我的指令更快,并且在我从 DOM 中删除小部件之前,一些 ajax 请求被发送到服务器.我需要指令在其子元素中停止控制器.

    我希望它是可以理解的...这里正在测试 Fiddle

    谢谢大卫

    解决方案

    我在上一个项目中使用了 angularjs 身份验证拦截器.它适合您的需要..

    拦截器存储每个服务请求和广播消息的请求.您可以在控制器上接收广播消息.这是我处理的代码..结帐身份验证拦截器.

    /*** @license HTTP Auth 拦截器模块,用于 AngularJS* (c) 2012 Witold Szczerba* 许可证:麻省理工学院*/angular.module('http-auth-interceptor', []).provider('authService', function() {/*** 保存所有因 401 响应而失败的请求,* 以便将来在登录完成后重新请求它们.*/var 缓冲区 = [];/*** HTTP 拦截器需要.* 附加到提供者的功能对于此服务的普通用户是不可见的.*/this.pushToBuffer = 函数(配置,延迟){缓冲推({配置:配置,延期:延期});}this.$get = ['$rootScope','$injector', function($rootScope, $injector) {var $http;//由于循环依赖问题稍后初始化功能重试(配置,延迟){$http = $http ||$injector.get('$http');$http(config).then(function(response) {deferred.resolve(响应);});}函数 retryAll() {for (var i = 0; i < buffer.length; ++i) {重试(缓冲区[i].配置,缓冲区[i].延迟);}缓冲区 = [];}返回 {登录确认:函数(){$rootScope.$broadcast('event:auth-loginConfirmed');$rootScope.$apply();//retryAll();}}}]})/*** $http 拦截器.* 在 401 响应中 - 它存储请求并广播event:angular-auth-loginRequired".*/.config(function($httpProvider, authServiceProvider) {var 拦截器 = ['$rootScope', '$q',function($rootScope, $q,$cookies) {功能成功(响应){返回响应;}函数错误(响应){如果(响应.状态 === 401){var deferred = $q.defer();authServiceProvider.pushToBuffer(response.config, deferred);$rootScope.$broadcast('event:auth-loginRequired');返回 deferred.promise;}else if (response.status === 404 || response.status === 400) {$rootScope.$broadcast('event:not-found');}//除此以外返回 $q.reject(response);}返回函数(承诺){返回 promise.then(success, error);}}];$httpProvider.responseInterceptors.push(interceptor);});

    在你的控制器中:

    $rootScope.$on('event:auth-loginRequired', function() {//做你想做的事,例如抛出一条消息});

    I'm resolving rights in AngularJS application... I would like to use custom directive for resolving what user can see by his role. It's only client side design. If user entry on page what he hasn't access, server return 403 for all requests for data from this page. My actual solution looks like this:

    <li ng-repeat="menuItem in navigationItems" class='{{menuItem.css}}' restrict-access="menuItem.restrict"> <a href="#/{{menuItem.url}}"> <div class="label"> <span class="icon"> <span class="title">{{menuItem.title}}</span> </span> </div> </a> </li>

    .directive('restrictAccess', function() {
        return {
            restrict: 'EA',
            prioriry: 100000,
            scope: {
                restrictAccess: "=restrictAccess"
            },
            controller: ['$scope', '$element', function($scope, $element) {
    
                var accessDenied = true;
                var userRole = App.LoggedUser.userRole;
    
                var attributes = $scope.restrictAccess.split(" ");
                for (var i in attributes) {
                    if (userRole == attributes[i]) {
                        accessDenied = false;
                    }
                }
    
                if (accessDenied) {
                    $element.remove();
                }
    
            }]
        };
    })
    

    There are many problems...

    Controllers of widgets rendered by ng-include are faster than my directive and some ajax requests are sended to server before I remove widgets from DOM. I need directive what stops controllers in their child elements.

    I hope it is understandable... Here is testing Fiddle

    Thanks David

    解决方案

    I used angularjs authentication interceptor in my last project. It suits what you need..

    Inteceptor stores the request on every service request and broadcast message.. You can get broadcasted messages on your controllers. Here is the code I dealt with.. Checkout auth interceptor.

    /**
     * @license HTTP Auth Interceptor Module for AngularJS
     * (c) 2012 Witold Szczerba
     * License: MIT
     */
    angular.module('http-auth-interceptor', [])
    
        .provider('authService', function() {
            /**
             * Holds all the requests which failed due to 401 response,
             * so they can be re-requested in future, once login is completed.
             */
            var buffer = [];
    
            /**
             * Required by HTTP interceptor.
             * Function is attached to provider to be invisible for regular users of this service.
             */
            this.pushToBuffer = function(config, deferred) {
                buffer.push({
                    config: config,
                    deferred: deferred
                });
            }
    
            this.$get = ['$rootScope','$injector', function($rootScope, $injector) {
                var $http; //initialized later because of circular dependency problem
                function retry(config, deferred) {
                    $http = $http || $injector.get('$http');
                    $http(config).then(function(response) {
                        deferred.resolve(response);
                    });
                }
                function retryAll() {
                    for (var i = 0; i < buffer.length; ++i) {
                        retry(buffer[i].config, buffer[i].deferred);
                    }
                    buffer = [];
                }
    
                return {
                    loginConfirmed: function() {
                        $rootScope.$broadcast('event:auth-loginConfirmed');
                        $rootScope.$apply();
                        //retryAll();
                    }
                }
            }]
        })
    
    /**
     * $http interceptor.
     * On 401 response - it stores the request and broadcasts 'event:angular-auth-loginRequired'.
     */
        .config(function($httpProvider, authServiceProvider) {
    
            var interceptor = ['$rootScope', '$q',function($rootScope, $q,$cookies) {
                function success(response) {
                    return response;
                }
    
                function error(response) {
                    if (response.status === 401) {                  
                        var deferred = $q.defer();
                        authServiceProvider.pushToBuffer(response.config, deferred);
                        $rootScope.$broadcast('event:auth-loginRequired');
                        return deferred.promise;
                    }
                    else if (response.status === 404 || response.status === 400) {
    
                        $rootScope.$broadcast('event:not-found');
                    }
                    // otherwise
                    return $q.reject(response);
                }
    
                return function(promise) {
                    return promise.then(success, error);
                }
    
            }];
            $httpProvider.responseInterceptors.push(interceptor);
        });
    

    And in your controller :

    $rootScope.$on('event:auth-loginRequired', function() {
         //do what you want, for example throw a message        
    });
    

    这篇关于在 AngularJS 指令中高级操作 DOM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆