【问题标题】:Can't access value of scope in AngularJS. Console log returns undefined无法访问 AngularJS 中范围的值。控制台日志返回未定义
【发布时间】:2014-04-29 20:42:01
【问题描述】:

我将 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.profile 时,控制台返回未定义。有什么想法吗?

编辑:添加我的 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>

更新:通过在子控制器中设置这样的观察者解决了这个问题。感谢@jonathanpglick 和@Nix 的帮助。

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

【问题讨论】:

  • 请发一个告诉你ui-router config的blub。
  • 添加了 ui-router 配置和部分。
  • 谢谢。我在下面发布了答案。

标签: angularjs angularjs-scope


【解决方案1】:

$scope.profile 是在异步请求之后设置的,所以我怀疑第二个控制器在user.get() 返回并为$scope.profile 赋值之前被实例化。

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

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

更新:

我刚刚意识到您正在使用 ui-router,因此有一种更简单的方法可以做到这一点。 ui-router 有一个 resolve 对象,您可以使用它来将类似这样的东西依赖注入到您的控制器中。每个解析函数只需要返回一个值或一个承诺,它就可以通过解析键名注入到控制器中。对你来说它看起来像这样:

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;
}]);

【讨论】:

  • 啊,谢谢,我还是有点迷失了观察和决心。但我得到了它的工作。我猜需要更多地阅读文档中的 $scope。
  • 嗯,我的手表还是有问题。我知道这是正确的方法,只是不确定如何实施。我在问题的末尾添加了一些代码,看看我是否做得对。
  • 我设置了一个观察者,但我收到了一个错误。你能看一下,看看可能是什么问题。
  • 是的,我忘了提到最初的配置文件值将作为null
【解决方案2】:

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

你的问题是:

  1. mainController控制器初始化并调用user.get()
  2. getTopicsController 初始化并记录 console.log($scope.profile)
  3. user.get() 的调用返回并设置范围。

这是一个常见问题,如果您需要保证设置了$scope.profile,请使用resolve 或观察变量。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-30
    • 2015-11-22
    相关资源
    最近更新 更多