Сервисная переменная, не обновляемая в контроллере
У меня есть NavbarCtrl, который находится вне ng-view. У меня есть контроллер входа, который разговаривает с сервисом, чтобы войти в систему. Как только пользователь вошел в систему, я хочу, чтобы Navbar обновлялся с помощью адреса электронной почты пользователя. Однако для моей жизни я не могу заставить область Navbar обновлять данные, загруженные в мою службу "Auth" после входа пользователя в систему.
Это мой основной index.html:
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="#">Brim</a>
<div class="pull-right" ng-controller="NavbarCtrl">
<div ng-click="refresh()">hello</div>
{{ user.email }}
</div>
</div>
</div>
</div>
<div class="container" ng-view>
И мое обслуживание:
.factory('Auth', function($resource) {
var authenticated = false;
var user = {};
return {
isAuthenticated: function () {
return authenticated;
},
getUser: function() {
return user;
},
login: function(loginUser, callback) {
user = {email:'[email protected]'}
authenticated = true;
callback(true);
//actual code for logging in taken out for brevity
}
}
})
И мои контроллеры Login и Navbar:
function LoginCtrl($scope, $location, Auth) {
$scope.login = function() {
Auth.login($scope.user, function(success) {
if(success) $location.path('/dashboard');
//console.log(Auth.getUser())
});
}
}
function NavbarCtrl($scope, Auth) {
//thought this should work
$scope.user = Auth.getUser();
//experimenting unsuccessfully with $watch
$scope.$watch(Auth.isAuthenticated(),function () {
$scope.user = Auth.getUser()
})
//clicking on a refresh button is the only way I can get this to work
$scope.refresh = function() {
$scope.user = Auth.getUser()
}
}
Из моего исследования я бы подумал, что $scope.user = Auth.getUser(); будет работать, но это не так, и я нахожусь в полной мере относительно того, как я могу обновить свой Navbar при входе пользователя в систему. Заранее благодарим за любую помощь.
Ответы
Ответ 1
Обновить: хорошо, вы узнаете что-то новое каждый день... просто удалите ()
, чтобы посмотреть результаты функции:
$scope.$watch(Auth.isAuthenticated, function() { ... });
Обновленная скрипка
В этой скрипке обратите внимание, как "watch1" и "watch3" запускают второй раз, когда изменяется значение $scope.isAuthenticated
.
Итак, это общий метод следить за изменениями примитивного значения, которое определено в службе:
- определить API/метод, который возвращает (значение) примитив
- $смотреть этот метод
В следить за изменениями в объекте или массиве, которые определены в службе:
- определить API/метод, который возвращает (ссылку) объект/массив
- В службе, будьте осторожны, чтобы только изменить объект/массив, не переназначьте его.
Например, не делайте этого: user = ...;
Скорее сделайте это: angular.copy(newInfo, user)
или это: user.email = ...
- Обычно вы назначаете локальное свойство $scope результатом этого метода, поэтому свойство $scope будет ссылкой на фактический объект/массив
- $смотреть свойство области
Пример:
$scope.user = Auth.getUser();
// Because user is a reference to an object, if you change the object
// in the service (i.e., you do not reassign it), $scope.user will
// likewise change.
$scope.$watch('user', function(newValue) { ... }, true);
// Above, the 3rd parameter to $watch is set to 'true' to compare
// equality rather than reference. If you are using Angular 1.2+
// use $watchCollection() instead:
$scope.$watchCollection('user', function(newValue) { ... });
Оригинальный ответ:
Чтобы просмотреть результаты функции, вам необходимо передать $watch функцию, которая обертывает эту функцию:
$scope.$watch( function() { return Auth.isAuthenticated() }, function() { ... });
Fiddle. В скрипке обратите внимание, как только "watch3" запускает второй раз, когда изменяется значение $scope.isAuthenticated
. (Сначала они запускаются, как часть инициализации $watch.)
Ответ 2
Попробуйте изменить
$scope. $watch (Auth.isAuthenticated(), function() { $ scope.user = Auth.getUser() })
к
$scope. $watch (Auth.isAuthenticated(), function() { $ scope.user = Auth.getUser() }, true)
Посмотрите документацию AungularJs $ для подробного объяснения, значение по умолчанию - false, что означает, что Angular обнаруживает изменения в первом значения параметров по ссылке, а передача истины означает, что проверка выполняется путем равенства. Если параметр является функцией, проверка возвращает всегда false, так как ссылка на функцию всегда одинакова.
Ответ 3
Использование user
, так как ваше имя переменной обычно не является хорошей идеей. Я когда-то менял его ti currentUser
все работало для меня.