$resolve在创建控制器之前不会添加到$scope

$resolve not added to $scope until after controller creation

本文关键字:添加 scope resolve 创建 控制器      更新时间:2023-09-26

我正在尝试利用(1.5.0 中的新功能)功能,该功能将解析图添加到路由范围内。 但是,在控制器加载之前,地图似乎实际上并没有添加到范围中。

这是一个非常简单的模块,演示了这个问题(来自这个 plunk):

var app = angular.module("app", ['ngRoute']);
app.config(['$routeProvider', '$locationProvider',
  function($routeProvider, $locationProvider) {
    $routeProvider.otherwise({
      controller: "editController",
      controllerAs: "ec",
      templateUrl: "edit.html",
      resolve: {
        resolveData: function() {
          return {
            foo: "bar",
            blah: "halb"
          }
        }
      }
    });
  }
]);
app.controller("editController", ["$scope", function($scope) {
  // undefined
  console.log($scope.$resolve);
  setTimeout(function() {
    // the object is there, including $scope.$resolve.resolveData
    console.log($scope.$resolve);
  }, 0)
}]);

如果您观看控制台,您会注意到创建控制器时undefined $scope.$resolve。但是,正如setTimeout所证明的那样,它紧接着就在那里。

我在文档中找不到任何表明应该如此的内容。 这是一个错误吗? 还是我只是对角度的工作原理没有了解?

如果其他人遇到这种情况 - 它已经在角度 github 上报告并作为预期行为解决。 $scope.$resolve 并不是真正打算在控制器中使用。 你应该注入它,或者使用$route.current.locals。

(或者,您可以使用 $scope.$resolve 将代码包装在$timeout中。

请注意,您的对象比您预期的要大得多,实际上您的对象位于$resolve上。这主要在文档中进行了解释,但是,可以通过示例更详细

...

解析地图将在路由范围内可用,在 $resolve

无需深入研究,当您resolve时,命名对象将成为可注射物,然后您可以放在$scope上,在这种情况下,resolveData。观察以下内容...

app.controller('editController', ['$scope', 'resolveData', function($scope, resolveData) {
  console.log(resolveData);
  // -- $scope.data = resolveData; // -- assign it here
}]);

普伦克 - 更新的演示


调查您获得undefined的原因是由于框架中等待摘要周期的性质。处理$resolve的一个可接受的解决方法包括将调用注入和包装在$timeout中,这会强制一个摘要循环,在该循环中,您的对象将在异步回调中可用。如果这种方法不理想,请放弃注入$timeout,直接为已解析的对象调用$route.current.locals,或者将对象作为命名参数注入,如上例所示,它将立即解析该参数。