2015-10-21 5 views
1

Следующие работы для меня:свойство объекта не определено в AngularJS

HTML:

{{user.uid}} 

JS:

"use strict"; 

app.controller('Ctrl', function($scope, Auth) { 

$scope.user = Auth.user; 
}); 

но

HTML:

{{uid}} 

JS:

app.controller('Ctrl', function($scope, Auth) { 
$scope.uid = Auth.user.uid; 
}); 

не работает, и это потому, что Auth.user.uid не определен! Почему это происходит? Почему мы можем называть атрибуты в представлении, но не внутри контроллера? Что делать, если я хочу вызвать атрибут внутри контроллера?

+2

ли 'Auth.user' вернуть обещание? – Claies

+0

@Claies моя догадка что-то еще заполняет 'Auth.user' асинхронно. Это не было бы обещанием – Phil

+0

@Phil да, как обещание от '$ http'. в любом случае, не видя кода для 'Auth', мы можем только догадываться о реальной проблеме. – Claies

ответ

3

Это может произойти, потому что в то время, когда вы назначаете Auth.user.uid в область действия, этот атрибут не существует. Он назначается в более позднее время на объект user, но поскольку вы сопоставили это значение непосредственно с $scope, оно не будет обновлять способ, которым вы хотите. Вот пример того, как это могло произойти:

.service('Auth', function($http){ 
    this.user = {}; 
    // this server call takes some amount of time to complete, 
    // and until it does user.uid is undefined 
    var self = this; 
    $http.get('http://someurl', function(result){ 
     self.user.uid = result.uid; 
    }); 
}); 

.controller('MyCtrl', function($scope, Auth){ 
    // this is called before the $http call is completed inside Auth 
    $scope.uid = Auth.user.uid; 

    // this is also called before the $http call completed, but because user exists, its children cause a scope change and notification 
    $scope.user = Auth.user; 
}); 

Теперь, как вы едите его работу, путь связывания user объекта с областью является гораздо лучшим способом сделать это в любом случае. Хорошей практикой является привязка объектов контейнера только к $scope.

+2

Чтобы уточнить, это разрешение '$ http', которое вызывает цикл дайджеста, тем самым обновляя шаблон. Объект ссылки JavaScript означает, что 'Auth.user' - это тот же объект, что и' $ scope.user' – Phil

+0

Просто интересно - почему хорошая практика только привязывать объекты контейнера к $ scope? – user124577

+0

Прежде всего, потому что вы гарантируете уровень $ scope, к которому вы пытаетесь получить доступ (что важно для таких вещей, как ng-model). Просто исследуйте, как работают угловые иерархии областей и почему точка важна. –

Смежные вопросы