2015-10-21 60 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' promise解析,从而更新了模板。 JavaScript的对象引用意味着'Auth.user'与'$ scope.user'是同一个对象 – Phil

+0

只是想知道 - 为什么只是将容器对象绑定到$ scope? – user124577

+0

主要是因为您保证您尝试访问的$ scope级别(对于ng-model等也很重要)。只要研究角度范围层次结构如何工作,以及为什么一个点很重要。 –