无法访问AngularJS中的范围值。控制台日志返回undefined

时间:2014-04-29 20:42:02

标签: angularjs angularjs-scope

我正在为我的应用程序使用ui-router并在ui-view中嵌套控制器。我的父控制器如下所示:

'use strict';

angular.module("discussoramaApp").controller("mainController", ["RestFullResponse", "Restangular", "localStorageService", "$scope", function(RestFullResponse, Restangular, localStorageService, $scope){

  var currentId = localStorageService.get("***");

  var user = Restangular.one("users", currentId);
  var Profile = user.get({}, {"Authorization" : localStorageService.get('***')}).then(function(profile) {
    $scope.profile = profile;
  });

}]);

我的孩子控制器:

'use strict';

angular.module("discussoramaApp").controller("getTopicsController", ["RestFullResponse", "Restangular", "localStorageService", "$scope", function(RestFullResponse, Restangular, localStorageService, $scope){

  var topics = Restangular.all('topics');
  var allTopics = topics.getList({},{"Authorization" : localStorageService.get('***')}).then(function(topics){
    $scope.topics = topics;
  });

  console.log($scope); // this works
  console.log($scope.profile); // this returns undefined

}]);

我遇到的问题是在子控制器中获取配置文件的继承$ scope值。当我记录$ scope时,配置文件在控制台中清晰可见。

$scope console log

但是当我尝试记录$ scope.profile时,控制台返回undefined。有什么想法吗?

编辑:添加我的ui-router配置。

angular.module("discussoramaApp").config(
  function($stateProvider, $urlRouterProvider){
    $urlRouterProvider.otherwise('/home');
    $urlRouterProvider.when('', '/home');

    $stateProvider

      .state('main',{
        url: '',
        templateUrl: 'partials/main.html',
        requireLogin: true
      })

      .state('main.home',{
        url: '/home',
        templateUrl: 'partials/main.home.html',
        requireLogin: true,
        title: 'Home'
      });

  }
);

以及相应的html文件:

// main.html
<div ng-controller="mainController">

  <div class="container">
    <div ui-view></div>
  </div>

</div>

和子html部分:

// main.home.html
<div ng-controller="getTopicsController">
  <div ng-repeat="topic in topics | filter:search">
    <a ui-sref="main.topic({id: topic.id})">{{ topic.topic_title }}</a>
  </div>
</div>

UPDATE :在子控制器中使用这样设置的观察器解决了这个问题。感谢@jonathanpglick和@Nix的帮助。

$scope.$watch('profile', function(profile) {
  if(profile) {
    $window.document.title = "Discussorama | " + profile.user.name;
  }
});

2 个答案:

答案 0 :(得分:2)

在异步请求之后设置了

$scope.profile所以我怀疑第二个控制器在user.get()返回之前被实例化并将值赋给$scope.profile

我认为您需要在子控制器中设置一个观察者(如$scope.$watch('profile', function(profile) {});),以便在配置文件可用或更改时执行操作。

此外,您在控制日志profile时可以在$scope上看到$scope密钥的原因可以在此解释:https://stackoverflow.com/a/7389177/325018。您需要使用console.dir()来获取对象的当前状态。

<强>更新

我刚刚意识到你正在使用ui-router,所以有更简单的方法来做到这一点。 ui-router有一个resolve对象,你可以使用它来依赖注入这样的东西到你的控制器。每个解析函数只需要返回一个值或一个promise,它就可以使用解析密钥名称注入控制器。它看起来像这样:

angular.module("discussoramaApp").config(
  function($stateProvider, $urlRouterProvider){
    $urlRouterProvider.otherwise('/home');
    $urlRouterProvider.when('', '/home');

    $stateProvider

      .state('main',{
        url: '',
        templateUrl: 'partials/main.html',
        requireLogin: true,
        resolve: {
          profile: ['Restangular', 'localStorageService', function(Restangular , localStorageService) {
            var currentId = localStorageService.get("***");
            var user = Restangular.one("users", currentId);
            return user.get({}, {"Authorization" : localStorageService.get('***')});
          }
        }
      })

      .state('main.home',{
        url: '/home',
        templateUrl: 'partials/main.home.html',
        requireLogin: true,
        title: 'Home'
      });

  }
);

angular.module("discussoramaApp").controller("mainController", ["profile", "$scope", function(profile, $scope){
  $scope.profile = profile;
}]);

答案 1 :(得分:1)

仅仅因为你有嵌套的范围,并不意味着在实例化嵌套的user.get()之前它会等待getTopicsController返回。

您的问题是:

  1. mainController控制器初始化并调用user.get()
  2. getTopicsController初始化并记录console.log($scope.profile)
  3. user.get()的调用将返回,然后设置范围。
  4. 这是一个常见问题,如果您需要设置$scope.profile,请使用resolve或观看变量。

    我实际上在今天早些时候举例说明了如何做到这一点:AngularJS $rootScope.$broadcast not working in app.run