2016-12-14 4 views
2

Я только начал изучать стек MEAN и пытаюсь создать страницу аутентификации с нуля (хотя я знаю, что могу использовать из коробки но я делаю это, чтобы иметь фоновые знания), но я считаю, что немного сложно обновить тексты на моем навигаторе. Мой index.html выглядит следующим образом;Как передать данные из ng-view в navbar, расположенные в index.html в Agularjs

<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) заменяет ссылку на службы в памяти объекту «пользователь» после того, как предыдущий объект пользователя (и ссылка в памяти) был привязан к $ scope от HeadController. Есть несколько способов, чтобы исправить это:

1. Mutate (вместо замены) исходного объекта с setUser:

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

2. сделать динамическую ссылку на «имя» в шаблоне

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

3. (предпочтительный выбор ИМО, хотя, безусловно, не самый простой в реализации) Сделать у.е. стоп-обработчиков событий в вашем пользовательском сервисе, чтобы при вызове 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 Google. – jbmilgrom