我刚刚开始学习MEAN stack,并试图从头开始构建一个身份验证页面(尽管我知道我可以使用开箱即用的身份验证,但这样做是为了了解背景),但我发现更新导航栏上的文本有点棘手。
我的index.html是这样的;

<nav class="navbar navbar-default navbar-fixed-top" ng-controller="HeadController">
 <div class = "container-fluid">
  <ul class="nav navbar-nav navbar-right">
     <li><a href="#">{{user.name}}</a></li>
  </ul>
 </div>
</nav>
<div class="container" ng-view></div>

我的app.js是这样的;
var app = angular.module('app',['ngRoute'])
     .service("userService", function () {
         this.user = {};
         this.getUser = function () {
            return this.user;
         };
         this.setUser = function (user) {
            this.user = user;
         };
      })
      .config(['$routeProvider', function ($routeProvider) {
         $routeProvider
           .when('/login', {
               templateUrl: 'partials/login.html',
               controller: 'LoginCtrl as login'
            })
           .when('/user/profile',{
              templateUrl: 'partials/profile.html',
              controller: 'ProfileCtrl as profile'
           })
           .otherwise({
               redirectTo: '/login'
            });
      }]);
   app.controller("HeadController", [
      '$scope',
      'userService',
      function ($scope, userService) {
       $scope.user = userService.getUser();
   }]);
  app.controller("LoginCtrl", [
      "$location",
      "userFactory",
      "userService",
      function ($location, userFactory, userService) {
         var login = this;
         login.user = {
            username: '',
            password: '',
            isRemember: true
         };
         login.login = function () {
            userFactory.login(login.user)
               .success(function (user) {
                  userService.setUser(user);
                  $location.path("/user/profile");
               })
               .error(function (err) {
                  console.log(err);
               });
         };
   }]);

最后,我的userFactory.js看起来是这样的;
 function login(user) {
            return $http({
               url: '/api/login/',
               method: "POST",
               data: user,
               headers: {
                  'Content-Type': 'application/json'
               }
            });
         }
return{login:login};

每当我登录时,我都希望{{user.name}}被更新,但这不会发生。我不知道怎么做。我能做些什么让这一切发生?

最佳答案

问题是userService.setUser(user)在先前的用户对象(和内存中的引用)绑定到HeadController的$scope之后,会替换服务在内存中对“user”对象的引用。有几种方法可以解决这个问题:
一。用setUser改变(而不是替换)原始对象:

this.setUser = function(newUserData) {
  angular.extend(this.user, newUserData);
};

2。在模板中动态引用“name”
<li><a href="#">{{ userService.getUser().name }}</a></li>

三。(IMO的首选,虽然肯定不是最容易实现的)在用户服务中创建自定义事件处理程序,以便在调用setUser时调用回调“侦听器”。这将允许您在HeadController中执行类似的操作:
userService.onUserUpdate(function(newUser) {
  $scope.user = newUser; // or userService.getUser();
});

要保持模板/视图更清晰、更具声明性,请使用当前的方式:
<li><a href="#">{{ user.name }}</a></li>

这可以像这样实现。在userService中添加:
var privateUserUpdateListeners = [];

this.onUserUpdate = function(cb)
  if (angular.isFunction(cb)) {
    privateUserUpdateListeners.push(cb);
    // Return a callback that can be used to deregister the listener.
    // In production code, you may want to wrap this function
    // to ensure that it may only get called once.
    return function() {
      var index = privateUserUpdateListeners.indexOf(cb);
      privateUserUpdateListeners.splice(index, 1);
    };
  }
};

this.broadcastUserUpdate = function(user) {
  privateUserUpdateListeners.forEach(function(cb) {
    cb(user);
  });
};

然后在setUser中可以添加如下广播:
this.setUser = function(user) {
  this.user = user;
  this.broadcastUserUpdate(user);
};

这应该能达到目的。

关于javascript - 如何将数据从ng-view传递到位于Angularjs中index.html的导航栏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41138300/

10-11 14:14