2016-03-26 14 views
2

私は一番上のコントローラを作成する前に約束を解決する方法を理解しようとしています。私はui.routerを使用していますので、異なるルートのコントローラの約束事を解決する方法を知っています。しかし、私は最初のコントローラがロードされる前にそれを解決する方法を知らない。MainControllerの約束を解決します

これは私の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> 

私は今シーズン(およびめったに変化し、他のデータ)をロードするサーバから、それは私のトップをコントローラに注入されています.htmlヘッダーといくつかの私のビューコントローラー。私は私の現在のシーズンをロードし、約束を返すサービスを持っている:

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

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

そして私は私のメインコントローラに注入し、この関数から解決を約束したいのですが:

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

は、どのように私は設定できますがこの? これはbody-elementを担当するコントローラ用です。だから私はまだここでルーティングを使用していません。

私は

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

のようなものが欲しいしかし、私はこれをどこに置くか分かりません。

+0

コンテンツを解決して非表示にしたり、いくつかの 'ng-if =" currentSeason "などで何かしたいという約束を待っているのはなぜですか?約束を待ってから、あるinit()内のパラメータで解決された値を渡すことでコントローラを呼び出すラッピングディレクティブを持つこともできます。loadCurrentSeason.then(function(currentSeason){$ scope.currentSeason = currentSeason;}) " 方法。 – floribon

+0

コンテンツを隠すことではありません。これは、この引数を必要とするサービスメソッドを呼び出すことに関するものです。もし私がちょうど少数のコントローラに入っていたら、私はあなたの提案について行くつもりです。しかし、私は数十のコントローラにこの値が必要です。 – EasterBunnyBugSmasher

+0

あなたのサービスは価値のあるものではなく約束を消費することができます。それは約束のアイデアです:それらを通常の値として操作し、必要なときには「then」を登録します。または、今シーズンの事柄が非常に特殊なものであれば、アプリケーションを起動する前に最初にロードしてから、 'angular.bootstrap(...)'を使ってコンパイルを開始することができます – floribon

答えて

2

少しあいまいです。

例:

//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()を使用することができます。

+0

現在、私のMainControllerを使ったビューは$ stateProviderの設定外です。私はあなたのソリューションのためにそれを変更する必要があると思いますか? – EasterBunnyBugSmasher

+0

ええ、私はそれをやるだろう。一般的には、外部のステートレスなセクションは大丈夫ですが、この場合、Angularは必要な 'config'の中に物事を持っています。そして、あなたはそれが一つの特定の状態に属していないことを表すことができるので、あなたが本当に何かを妥協していると思います。 –

+0

ルーティングを、抽象家の状態であなたの提案に変更しました。私はchildResolveを解決しようとすると解決されませんが、コントローラに正しく注入されます。私がそれをデバッグするとき、それは未定義です。私はそれのための回避策があります。 – EasterBunnyBugSmasher

0

は、私は、これはあなたが求めているものだと思うのルーティング設定

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

}) 

で決意を使用してください。質問は、あなたが抽象親個々前に解決される状態、具体的な子のルート解決さ(したがってでそれらの解決に使用することができます)のための決意を持つことができます

+0

それは私のindex.htmlで動作するでしょうか? (私はそれを少し明確にするために質問を編集しました) – EasterBunnyBugSmasher

+0

いいえ...あなたは元の質問からあまりにも多くの情報を残しました。 – charlietfl

0
イースターバニー

私は非常に似たジレンマを持っていました。ちなみに、問題はコントローラがロードされる前に約束を解決するのではなく、ページがロードされる前に約束を解決して、データレスページが表示されないようにすることです。

マイソリューション

  1. 第一歩。約束が解決されるまでページ/テンプレートをロードしたくない。意味、表示するデータがあるまで。そのためには、ngIfで、ngShowではなく、 "ngIf"は条件が真である場合、つまりデータが存在する場合にのみページを表示します。

  2. データがロードされた(つまり、約束が解決された)かどうかを示す変数を 'MainController'に保持させ、ngIfでその変数を監視させます。

これについては、約束によって返されたデータを保持するサービス(またはそれを呼び出すサービスモデル)を作成します。コントローラで

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

    var dataModel= this; 

    var dataModel.someData = {}; 

    return dataModel; 
}); 

、約束コールバック関数内でデータを取り込むと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> 

あなたのためにもうまくいくと思います。

+0

それは表示に関するものではありません。これは、実行中のコントローラコードに関するものです。各コントローラごとに、これらのデータ値を後続のクエリのパラメータとして使用する前に、ロードする5〜8個の非常に静的なデータ(サーバーからの)のサブセットが必要です。私は、作業を開始する前に、すべてのコントローラが3-4の約束がすべて解決されるのを待つように、すべてのコントローラをプログラムしたくありません。私はそれらを解決された状態でコントローラに注入します。 – EasterBunnyBugSmasher

関連する問題