简体   繁体   中英

Service variable not updating directive in Angular JS

I think this is a scoping problem, but I can't get my head around this.

I have a service as below:

(function (module) {

var portalService = function ($timeout, $http, $q, alerting, $cookies, $cookieStore, STATUS_OK, STATUS_FAIL, APP_COOKIE) {


    var _permissions = {};

    var permissions = function ()
    {
        var def = $q.defer();

        if (loggedIn) {

            if (_.size(_permissions) > 0) {
                def.resolve({ status: STATUS_OK }, _permissions);
            }
            else {
                $http({
                    url: "/Auth/GetPermissionsAsync",
                    method: "POST",
                }).success(function (data, status, headers, config) {
                    if (data.result.status == STATUS_OK) {
                        _permissions = data.permissions;
                    }
                    def.resolve(data.result, data.permissions);

                }).error(function (data, status, headers, config) {
                    def.reject("Failed to retrieve permissions.", status);
                });
            }


        }
        else {
            def.resolve({ status: STATUS_OK }, _permissions);
        }
        return def.promise;

    }



    var logOn = function (email, password) {
            var def = $q.defer();
            $http({
                url: "/Auth/LogInAsync",
                method: "POST",
                data: { email: email,
                        password: password},
            }).success(function (data, status, headers, config) {
                //testing if we can even update this...
                _permissions=[{parent: "Administer", items: [{name: "Users", route: "dashboard"}]}];
                def.resolve(data.result);

            }).error(function (data, status, headers, config) {
                    def.reject("Failed to contact the server to log in.",status);
            });
            return def.promise;
    };

    var register = function (data) {
        var def = $q.defer();
        $http({
            url: "/Auth/RegisterAsync",
            method: "POST",
            data: data
            ,
        }).success(function (data, status, headers, config) {
                def.resolve(data.result);
        }).error(function (data, status, headers, config) {
            def.reject("Registration failed to contact the server",status);
        });
        return def.promise;
    };

    var logOut = function (data) {
        var def = $q.defer();
        $http({
            url: "/Auth/SignOutAsync",
        }).success(function (data, status, headers, config) {
            _permissions = {};
            def.resolve(data.result);
        }).error(function (data, status, headers, config) {
            def.reject("Signing out failed to contact the server.", status);
        });
        return def.promise;
    };

    var loggedIn = function ()
    {
        if ($cookies.get(APP_COOKIE))
            return true;
        else
            return false;
    }

    var currentPermissions = function ()
    {
        return _permissions;
    }


    return {
        logOn: logOn,
        register: register,
        logOut: logOut,
        loggedIn: loggedIn,
        permissions: permissions,
        currentPermissions : _permissions
    };

};

module.factory("portalService", portalService);

}(angular.module("clportal")));

I have a directive as below:

    (function (module) {

    var navMenu = function (portalService) {
        return {
            restrict: "AE",
            templateUrl: "/Template/NavMenu",
            scope: true,
            link: function(scope, element, attributes) {

                scope.permissions = portalService.currentPermissions;
            }
        };
    };

    module.directive("navmenu", navMenu);

}(angular.module("clportal")));

And, I have the inclusions as below:

 <!DOCTYPE html> <html lang="en" ng-app="clportal"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags --> <meta name="description" content=""> <meta name="author" content=""> <link rel="icon" href="/favicon.ico"> <title>Navbar Template for Bootstrap</title> <!-- Bootstrap core CSS --> <!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" integrity="sha512-dTfge/zgoMYpP7QbHy4gWMEGsbsdZeCXz7irItjcC3sPUFtf0kuFbDz/ixG7ArTxmDjLXDmezHubeNikyKGVyQ==" crossorigin="anonymous"> <link rel="stylesheet" href="~/lib/angular-growl-v2/build/angular-growl.min.css" /> <link rel="stylesheet" href="~/lib/angular-ui-router-anim-in-out/css/anim-in-out.css" /> <link rel="stylesheet" href="~/lib/font-awesome/css/font-awesome.min.css"> <!-- Custom styles for this template --> <link href="~/css/site.css" rel="stylesheet"> <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> <![endif]--> </head> <body> <div class="container"> <!-- Static navbar --> <div ng-controller="navController"> <nav class="navbar navbar-default" role="navigation"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle" ng-init="navCollapsed = true" ng-click="navCollapsed = !navCollapsed"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Customer Center</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" ng-class="!navCollapsed && 'in'"> <navmenu></navmenu> </div><!-- /.navbar-collapse --> </nav> </div> <!-- Main component for a primary marketing message or call to action --> <div growl inline="true" reference="global"></div> <div class="row" > <route-loading-indicator></route-loading-indicator> <div ng-if="!isRouteLoading" ui-view="" class="col-lg-12 anim-in-out anim-fade" data-anim-speed="1000" ></div> </div> </div> <!-- /container --> <!-- Bootstrap core JavaScript ================================================== --> <!-- Placed at the end of the document so the pages load faster --> <script src="~/lib/angular/angular.min.js"></script> <script src="~/lib/angular-ui-router/release/angular-ui-router.min.js"></script> <script src="~/lib/angular-messages/angular-messages.min.js"> </script> <script src="~/lib/angular-sanitize/angular-sanitize.min.js"></script> <script src="~/lib/angular-animate/angular-animate.min.js"></script> <script src="~/lib/angular-bootstrap/ui-bootstrap-tpls.min.js"></script> <script src="~/lib/angular-cookies/angular-cookies.min.js"></script> <script src="~/lib/angular-ui-router-anim-in-out/anim-in-out.js"></script> <script src="~/js/app/app-clportal.js"> </script> <script src="~/lib/angular-growl-v2/build/angular-growl.min.js"></script> <script src="~/js/app/services/exceptionHandler.js"></script> <script src="~/js/app/services/portalService.js"> </script> <script src="~/js/app/services/alerting.js"></script> <script src="~/js/app/directives/alert.js"></script> <script src="~/js/app/directives/compareDirective.js"> </script> <script src="~/js/app/directives/formInput.js"></script> <script src="~/js/app/controllers/homeController.js"> </script> <script src="~/js/app/controllers/loginController.js"> </script> <script src="~/js/app/controllers/registerController.js"> </script> <script src="~/js/app/directives/loadingView.js"></script> <script src="~/js/app/controllers/dashboardController.js"></script> <script src="~/js/app/controllers/navController.js"></script> <script src="~/js/app/directives/navMenu.js"></script> <script src="~/lib/underscore/underscore-min.js"></script> </body> </html> 

Now when I call the logOn method, via the portalService, in theory it should set the _permissions local variable, which then should update the appropriate directive navMenu so that it sees the new menu option, and renders appropriately. However this does not work. I can use simple examples and its fine, but there is something fundamentally wrong with the way I'm doing it, scoping wise I would assume and I can't see it.

Any help appreciated.

Thanks

It was just a simple bug - LogOff was being called before log on, and that was setting the local variable to an empty object - this basically cut off the reference that was stored against the directive.

So I needed to set the size to zero on the array if i wanted to clear it out, to make sure that the original reference wasn't lost, and use push to push new values to the array. Working fine now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM