解决 MainController 的承诺

resolve a promise for the MainController

我正在尝试弄清楚如何在创建我的最顶层控制器之前解决承诺。我正在使用 ui.router 所以我知道如何为我的不同路线解决控制器的承诺。但是我不知道如何在我的第一个控制器加载之前解决它。

这是我的摘录 index.html:

<html lang="de" x-ng-app="myapp">
    <body x-ng-controller="MainController">
        ...
        <div id="header" x-ng-include="'top.html'"></div>
        ...
        <div id="viewDiv" ui-view></div>
        ...
    </body>
</html>

我想从服务器加载当前季节(以及其他很少更改的数据)并将其注入到我的 top.html header 和我的一些视图控制器的控制器中.我有一项服务可以加载我当前的季节和 returns 一个承诺:

services.factory('RestAccess', function(Restangular) {
    return {
        loadCurrentSeason : loadCurrentSeason
    };

    function loadCurrentSeason() {
        return Restangular.one('season','current').get();
    }
});

而且我希望在我的 MainController 中注入此函数的已解决承诺:

controllers.controller('MainController', function($scope, currentSeason, SomeService) {
    $scope.season = currentSeason;
    $scope.stuff = SomeService.loadStuff(currentSeason);
});

我该如何配置? 这是给负责 body-element 的 Controller 的。所以我还没有在这里使用任何路由。

我想要

resolve: {
    currentSeason : function(RestAccess) {return RestAccess.loadCurrentSeason();}
}

但是我不知道把它放在哪里。

在路由配置中使用解析

.state('someState',{
   url:'....',
   controller:'MainController',
   resolve:{
      currentSeason:function(SomeService){
         // return the promise needed to resolve for injected variable
         return SomeService.someMethod();
      }
   }

})

我想这就是你要问的。问题有点模糊

您可以对抽象父状态进行解析,该状态将在各个具体的子路由解析之前解析(因此可以在中使用 那些决心)。

示例:

//In module.config()...
...
$stateProvider
.state('home', {
    url:'/',
    template: '<div ui-view></div>',
    abstract: true,
    resolve: {
        'parentResolve':['yourService', function(yourService){ /*Return promise*/ }]
    }
})
.state('home.child', {
    url:'/child',
    template: '<div>After home</div>',
    controller: ['parentResolve', function(parentResolve){ /*Use parentresolve*/ }],
    resolve: {
        'childResolve':['parentResolve','yourService', function(parentResolve, yourService){ /*Parent resolve is available, as is service*/ }]
    }        
}
...

此外,您可以在尝试加载任何状态之前使用 module.run() 到 运行 某些东西。

先生复活节兔子,

我有一个非常相似的困境。顺便说一句,问题不在于您想要在控制器加载之前解决承诺,而是您想要在页面加载之前解决承诺以防止呈现无数据页面。

我的解决方案

  1. 第一步。在承诺解决之前,您不想加载 page/template 。意思是,直到有数据要显示。对于那个使用 ngIf, NOT ngShow,因为 "ngIf" 只会在我们的条件为真时呈现页面,即当存在数据时。

  2. 让 'MainController' 维护一个指示数据是否已加载的变量(意思是,承诺已解决),并让 ngIf 监视该变量。

为此,创建一个服务(或服务模型——随便你怎么称呼它)来保存承诺返回的数据。

angular('app').factory('dataServiceModel', function(){

   var dataModel= this;

   var dataModel.someData = {};

   return dataModel;
});

在控制器中,在 promise 回调函数中填充数据并设置变量让 ngIf 知道有数据要显示。

angular('app').controller('MainController', ['dataServiceModel'], function(){

var mainController = this;

mainController.loadedData = false;

mainController.getTheDataFromTheServer(){
      ... 
      ...
      { // Callback to the promise and on successful retrieval
        dataServiceModel.someData = ... the data ..
        mainController.loadedData = true
      }
   }
}); 

现在来自标记;

<ANY ng-controller="MainController as mainController"
  ng-if="mainController.loadedData">
...
</ANY>

我想这对你也有用。