2

SPA のすべてのビューに存在する永続的なメニューを含めるために、ng-include を使用しています。

問題は、各ユーザー タイプ (管理者、ゲスト、ユーザーなど) ごとにこのメニューに異なるオプションとコンテンツを表示したいことです。これには、サービス関数 authService.loadCurrentUser を最初に解決する必要があります。

このコンテンツを簡単かつ快適に管理する目的で、必要なアクセス レベルの属性を取得し、要素のコンパイル フェーズで、指定されたユーザーの権限が十分でない場合、属性を削除する簡単なディレクティブを作成しました。要素とそれは子です。

そのため、ng-include を routeProvider 関数を通過させようとして惨めに失敗した後、ng-init を使用しようとしましたが、何も機能していないようで、ログアウト時にユーザー ロールが未定義のままです。

メニュー全体を、ユーザータイプごとに適したテンプレートを含むディレクティブにするなど、新しいアプローチを試みようと考えていますが、まずはこの問題を解決することを試みたいと思います。

指令:

'use strict';
/* Directives */
angular.module('myApp.directives', []).
directive('restrict', function(authService){
    return{
        restrict: 'A',
        prioriry: 100000,
        scope: {
            // : '@'
        },
        link: function(){
            // alert('ergo sum!');
        },
        compile:  function(element, attr, linker){
            var user = authService.getUser();
                if(user.role != attr.access){
                console.log(attr.access);
                console.log(user.role);//Always returns undefined!
                    element.children().remove();
                    element.remove();           
                }

        }
    }
});

サービス:

'use strict';
/* Services */
angular.module('myApp.services', []).
factory('authService', function ($http, $q) {
    var authServ = {};
    var that = this;
    that.currentUser = {};
    authServ.authUser = function () {
        return $http.head('/users/me', {
            withCredentials: true
        });
    },
    authServ.getUser = function () {
        return that.currentUser;
    },
    authServ.setCompany = function (companyId) {
        that.currentUser.company = companyId;
    },
    authServ.loadCurrentUser = function () {
        var defer = $q.defer();
        $http.get('/users/me', {
            withCredentials: true
        }).
        success(function (data, status, headers, config) {
            console.log(data);
            that.currentUser.company = {};
            that.currentUser.company.id = that.currentUser.company.id ? that.currentUser.company.id : data.main_company;            
            that.currentUser.companies = [];
            for (var i in data.roles) {
                that.currentUser.companies[data.roles[i]['company']] = data.roles[i]['company_name'];
                if (data.roles[i]['company'] == that.currentUser.company.id){
                    that.currentUser.role = data.roles[i]['role_type']; 
                    that.currentUser.company.name = data.roles[i]['company_name'];
                    // console.log(that.currentUser.role);
                } 
            }
            // defer.resolve(data);
            defer.resolve();
        }).
        error(function (data, status, headers, config) {
            that.currentUser.role = 'guest';
            that.currentUser.company = 1;
            defer.reject("reject");
        });  
    return defer.promise;
    }

    return authServ;
});

メニューコントローラー:

angular.module('myApp.controllers', []).
controller('menuCtrl', function($scope, $route, $location, authService){
    //TODO: Check if this assignment should be local to each $scope func in order to be compliant with 2-way data binding
    $scope.user = authService.getUser();
    console.log($scope.user);
    // $scope.companies = $scope.user.companies;
    $scope.companyOpts = function(){
        // var user = authService.getUser();
        if(typeof $scope.user.company == 'undefined')
            return;

            var companies = [];
            companies[$scope.user.company.id] = $scope.user.company.name;
            for(var i in $scope.user.companies){
                if(i != $scope.user.company.id){
                    companies[i] = $scope.user.companies[i];    
                }
            }
            // console.log(companies);
            // if(nonCurrentComapnies.length > 0){
                console.log(companies);
                return companies;
            // }
    }



    $scope.$watch('user.company.name', function(company){
        for(var i in $scope.user.companies)
            if(company == $scope.user.companies[i].id)
                authService.setCompany(i);
    });
    $scope.$watch(function(){return authService.getUser().company; }, function(company){
        //Refresh the page on company change here, first time, and each time the user changes the select
        // $scope.companyOpts();
        // $scope.currentComapany = company;
    })
;})

メイン SPA HTML ページ:

<div ng-init="authservice.loadCurrentUser" ng-include src="'partials/menu.html'"></div>

管理者のみに表示されるメニュー要素:

<ul class="left" restrict access="admin">
  <li>You are the admin!</li>
</ul>

ご協力いただきありがとうございます。

4

2 に答える 2

1

私は個人的に「逆」の方法を行います。つまり、ユーザーの役割が「管理者」または「ユーザー」などの場合にメニューを追加します...

このようにして、「restrict」ディレクティブで次のようなことができます。

    ...
    var roleListener = $scope.$watch('user.role', function (newVal, oldVal) {
        if (newVal == $scope.access) {
            // add the menu items
            // supposed that loadcurrentuser be called only once
            // we should clear the watch
            roleListener();
        } else {
            // personally, I would remove the item here too
            // so the menu would be added or removed when user.role update
        }
    });
    ...

もう1つ、ユーザーロールに基づいてメニューベースを表示するには、次のようにngSwitchを使用できます。

    <ul class="left" ng-switch="user.role">
        <li ng-switch-when="admin">You are the admin!</li>
        <li ng-switch-when="user">You are the user!</li>
        <li ng-switch-default><img src="some-thing-running.gif"/>Your menu is loading, please wait...</li>
    </ul>

そして魔法の AngularJS バインディングがメニューをレンダリングします!

于 2013-08-22T09:51:55.110 に答える