2016-12-14 18 views
2

我剛開始學習MEAN堆棧,並試圖從頭構建一個認證頁面(儘管我知道我可以使用開箱即用身份驗證,但我這樣做有一個背景知識),但我覺得有點棘手更新我的導航欄上的文本。 我的index.html看起來像這樣;如何將數據從ng-view傳遞到位於Agularjs的index.html的navbar

<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}}被更新,但不會發生。我不知道如何完成這件事。我能做些什麼來做到這一點?

+0

給定您正在開始新的..使用組件和基於組件的路由..它會更容易理解... – harishr

+0

@entre請你能夠友好解釋嗎? –

回答

2

問題是userService.setUser(user)將先前的用戶對象(和內存中的引用)綁定到HeadController的$範圍之後,將內存中的服務引用替換爲「用戶」對象。有幾種方法來解決這個問題:

變異原始對象(而不是替換)與setUser

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

2.在模板製作一個動態參考「名」

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

(IMO的首選,但絕對不是最容易實現的)使銅在用戶服務中使用stom事件處理程序,以便在調用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); 
}; 

這應該做的伎倆。

+0

請你可以給你一個簡短的代碼片斷你的首選嗎? (即解決方案#3)。 –

+0

是啊當然,我會更新我的回答 – jbmilgrom

+0

@OchiFortune lemme知道這是否成立。如果你在開始時遇到困難(我知道我最初做過)並且感興趣,那麼你可能需要使用谷歌JavaScript觀察者模式。 – jbmilgrom

相關問題