angularjs 在控制器中承诺后更改根范围

angularjs change rootscope after promise in a controller

我正在尝试在收到来自服务的 promise 后从控制器中更改一些 $rootscope 变量

$rootscope变量用于设置html页面标题属性等

下面是我的代码,我创建了一个名为 changeRootPageNotFound() 的函数来更改 $rootscope 变量。如果在 promise.then 函数中调用它则不起作用。

app.controller('mainController', ['$routeParams', '$scope', '$rootScope', 'mainService', function ($routeParams, $scope, $rootScope, mainService) {
    var mainCtrl = this;
    mainCtrl.id = $routeParams.itemId;

    var promise = mainService.getData($routeParams.id);

    promise.then(function (response)
    {
        if (response.data.data) {
            mainCtrl.data = response.data.data;
        } else {
            mainCtrl.data = false;
            changeRootPageNotFound();
        }
    });
    function changeRootPageNotFound() {
        $rootScope.title = "Page Not Found - 404";
        $rootScope.titleSuffix = "";
    }
    // changeRootPageNotFound();  // works here
}]);

在收到服务的延迟承诺后,如何更改 $rootscope 变量?

根据您的代码片段,您的代码应该可以正常工作。在我的 plunker 中,它也在延迟承诺之后工作。

// Code goes here
angular.module('Test',[])
  .service('Service', function($q){
    this.ts = function(){
      var deferred = $q.defer();
      deferred.resolve("hello")
      return deferred.promise;
    }
  })
  .controller('Controller', function(Service, $rootScope){

    Service.ts().then(function(response){
      $rootScope.title="hello";
      changeRootPageNotFound();
    });

    function changeRootPageNotFound() {
        $rootScope.title = "Page Not Found - 404";
        $rootScope.titleSuffix = "";
    }
  });

这是html

<!DOCTYPE html>
<html>

  <head>
    <script data-require="angularjs@1.5.8" data-semver="1.5.8" src="https://opensource.keycdn.com/angularjs/1.5.8/angular.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-app="Test">
    <div ng-controller="Controller">

      <h1>{{title}}</h1>

    </div>
  </body>

</html>

请检查这个 Plunker https://plnkr.co/edit/THXDYrWuTqR8UYSJlerB?p=preview

添加一个.catch方法:

promise.then(function (response)
{
    //if (response.data.data) {
        mainCtrl.data = response.data.data;
    //} else {
    //    mainCtrl.data = false;
    //    changeRootPageNotFound();
    //}
}).catch(function(errorResponse) {
    console.log(errorResponse.status);
    mainCtrl.data = false;
    changeRootPageNotFound();
    throw errorResponse;
});

当状态超出 200-299 范围时,$http 服务拒绝承诺。


What is the throw errorResponse; for, can it be left out?

如果 throw errorResponse 被省略,拒绝处理程序 returns 的值为 undefined。这会将 转换 被拒绝的 promise 为一个 fulfilled promise,解析为 undefined。如果没有进一步的链接,它可以被忽略。

问题的一个常见原因是程序员没有意识到这一点并且无意中转换了 promise。


instead of .catch you can pass the same function to then as the 2nd argument

.catch 和使用 .then 方法的第二个参数之间的细微差别之一是 .then 成功处理程序中的运行时错误不会在拒绝中被捕获第二个参数的处理程序。