【问题标题】:How to pass data from ng-view to navbar located at index.html in Agularjs如何将数据从 ng-view 传递到位于 Angularjs 中 index.html 的导航栏
【发布时间】:2017-04-29 12:42:18
【问题描述】:

我刚开始学习 MEAN 堆栈并尝试从头开始构建身份验证页面(尽管我知道我可以使用开箱即用的身份验证但这样做是为了了解背景知识)但我发现了一点在我的导航栏上更新文本很棘手。 我的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}} 会更新,但这不会发生。我不知道该怎么做。我该怎么做才能做到这一点?

【问题讨论】:

  • 鉴于您是开始新的..使用组件和基于组件的路由..它会更容易理解...
  • @entre 请您解释一下好吗?

标签: javascript html angularjs twitter-bootstrap mean-stack


【解决方案1】:

问题在于userService.setUser(user) 在之前的用户对象(和内存中的引用)绑定到HeadController 的$scope 之后,将内存中的服务引用替换为“用户”对象。有几种方法可以解决这个问题:

1.setUser改变(而不是替换)原始对象:

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

2.在模板中动态引用“名称”

<li><a href="#">{{ userService.getUser().name }}</a></li>

3.(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);
};

这应该可以解决问题。

【讨论】:

  • 请您提供一个简短的代码 sn-p 您的首选? (即解决方案#3)。
  • @OchiFortune 让我知道这是否可行。如果你无法理解它(我知道我一开始就这样做了)并且感兴趣,你可能想谷歌 JavaScript 观察者模式。
  • 说得通但不放弃。我尝试应用它但仍然没有解决它。我会欣赏一个像 plurk 这样的工作示例。谢谢顺便说一句
猜你喜欢
  • 2019-06-15
  • 2020-11-13
  • 2021-02-08
  • 1970-01-01
  • 2019-12-29
  • 2018-07-20
  • 2020-02-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多