简体   繁体   中英

Angular.js $modal Scope issues

I am trying to create a simple login modal with username and password. To accomplish this, I used a factory for handling login variables across controllers:

.factory('userFactory', function($http) {
    var userInfo = {
        isLogged: false
    };  
    return {
        getUserInfo: function () {
            return userInfo;
        },


        loginNonce: function(loginObj) {
            return $http.get('http://exmple.com/?json=get_nonce&controller=auth&method=generate_auth_cookie').success(
            function(data, status, headers, config) {
                var nonce = data.nonce;
            }); 
        },

        login: function(loginObj) {
            var nonce = loginObj.nonce; 
            return $http.get('http://example.com/?json=auth/generate_auth_cookie&nonce='+nonce+'&username='+loginObj.username+'&password='+loginObj.password).success(function(data, status, headers, config) {
                if (data.status == 'ok') {

                    var userInfo = {
                        isLogged: true,
                        username: data.user.username,
                        userAvatar: data.user.avatar,
                        firstName: data.user.firstname,
                        lastName: data.user.lastname
                    }
                    return userInfo;
                } else {
                    var userInfo = {
                        isLogged: false,
                        username: '',
                        errorMsg: data.error
                    }
                    return userInfo;
                }
            })
            .error(function(data, status, headers, config) {
                var userInfo = {
                        isLogged: false,
                        username: '',
                        errorMsg: 'Server Error!'
                }
                return userInfo;
            });

        }
    }

});

Than I have a login controller that initiates the modal and handles the login attempts:

var loginController = function($scope, $http, $modal, userFactory) {
    $scope.userInfo = userFactory.getUserInfo();
    $scope.logged = $scope.userInfo.isLogged;
    $scope.open = function() {
        $scope.modalInstance = $modal.open({
        templateUrl: 'views/modal.html',
        controller: ModalInstanceCtrl,
        size: 'lg',
        resolve: {
            userInfo: function () {
                return $scope.userInfo;              
          }
        }
      });
    }
    $scope.login = function() {
        var loginObj = {
            username: $scope.username,
            password: $scope.password
        }
        var results = userFactory.login(loginObj);
        userFactory.loginNonce().then(function(data) {
            var nonce = data.data.nonce;
            loginObj.nonce = data.data.nonce;
            userFactory.login(loginObj).then(function(data) {
                if(data.data.error) {
                    $scope.errorMsg = data.data.error;
                } else {
                    $scope.ok();
                }
            }); 
        });
    }   
}

Here is the Modal Instance controller:

var ModalInstanceCtrl = function($scope, $modalInstance, $http, userFactory, userInfo) {
    $scope.userInfo = userFactory.getUserInfo(); 
    $scope.ok = function () {
        $modalInstance.close($scope.results);
        console.log(userInfo);
    };
    $scope.cancel = function () {
        $modalInstance.dismiss('cancel');
    };
} 

This is what the loginController partial looks like:

<div  id="main_bar" class="header" ng-controller="loginController">
  <ul class="nav nav-pills pull-right" >

    <li class="col-sm-3 col-md-3 col-lg-2 row  pull-right  userBlock" ng-show="logged"><div class="barAvatar" style="background-image: url({{ userAvatar }});"></div><div class="userName">{{ userFirstName }} {{ userLastName }} <span ng-click="logout()">Logout</span></div></li>
    <li ng-hide="logged" ><a ng-href="" ng-click="open()">Login</a></li>
    <li ng-hide="logged"><a ng-href="#/register">Signup</a></li>
  </ul>

</div>

This is the template partial for the login controller which displays the current user's information:

The login process works and the proper variables are set with the factory. However, I can't seem to get the updated userInfo object into the loginController's scope. I've used the console so I know the factory is working properly. I know this is probably a simple scope issue, but everything I have attempted has failed to work.

You need to add a success callback to your modal to be able to update userInfo on your LoginController scope. The first assignment to $scope.userInfo you have is only done when the controller gets instanciated.

$scope.open = function() {
    $scope.modalInstance = $modal.open({
    templateUrl: 'views/modal.html',
    controller: ModalInstanceCtrl,
    size: 'lg',
    resolve: {
        userInfo: function () {
            return $scope.userInfo;              
      }
    }
  }).result.then(function (userInfo) {
    $scope.userInfo = userInfo;
    // Or
    $scope.userInfo = userFactory.getUserInfo();
  });
}

Also in your modal you use both resolve and userFactory for obtaining the same information, you only need one of the two. And should your login function not be in the ModalInstanceCtrl?

Because of scope inheritance I typically dot.notation all my scope variables. I'd have a $scope.user.info. That way you can read up the scope chain and use that variable. (complex reading here: https://github.com/angular/angular.js/wiki/Understanding-Scopes#javascript-prototypal-inheritance )

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