2017-12-19 5 views
3

$ブロードキャストイベントで別のコントローラに問題が発生しました。だからここには取り引きがある。ウェブサイトのフッタには、別のコントローラがロードされています(CMSController)。また、私は、そのコントローラがロードしてCMSからヘルプセンターのデータを取得するルート '/ help'を持っています。 フッターにはこれに関連するリンクがあります。利用規約にリンクしています。そのデータを取得するには、私は '/ help'ルートに行き、getHelpPage()関数を呼び出す必要があります。それは私が取り組んでいる進行中のプロジェクト構造です。 だから私は「/ヘルプ」ルートにリダイレクトし、私はtheCMSControllerに聞いているイベントを、放送とルート変更時にコントローラが完全にロードされたことを検出しました

$scope.openHelpCenterPage = function openHelpCenterPage(slug) { 
    if($location.path().indexOf('/help') === -1){ 
     $location.path('/help'); 
    } 
     $rootScope.$broadcast('openHelpCenterPage', {slug: slug, from: 'footer'}); 
}; 

そしてCMSController

$rootScope.$on('openHelpCenterPage', function (event, obj) { 
     $scope.getHelpPage(obj.slug); 
}); 

でgetHelpPage()を呼び出しますよフッタから問題は、これが機能していないということです。私はtheCMSControllerが何が起こっている読み込まれていないと思います。コンソールにエラーはありません。しかし

.... $タイムアウトにboradcastをPuringすることも、0秒で、問題を解決します。..

$timeout(function() { 
     $rootScope.$broadcast('openHelpCenterPage', {slug: slug, from: 'footer'}); 
    },0); 

しかし、tiは良い解決策であるような気がしません。他のアイデア???私はまた、openHelpCenterPageを聞いた後$ routeChangeSuccessを聞くために試してみたが、やはり、何の結果....

$rootScope.$on('openHelpCenterPage', function (event, obj) { 
    $rootScope.$on('$routeChangeSuccess',function(){ 
    $scope.getHelpPage(obj.slug); 
    }) 
}); 

多分他の方法は、コントローラが完全にロードされるかどうかを検出しないように???? ありがとうございました。私は問題をうまく説明したいと思います。

+0

$ rootScopeの代わりに '$ scope。$ on(...)'を使って関連スコープのイベントを待ち受けようとしてください。 $ on(...) ';あなたが '$ broadcast'の代わりに' $ emit'を使うと、何か変わるでしょう( '$ emit'のために実際に' $ rootScope。$ on'が必要です)? –

+0

お返事ありがとうございます。残念ながら、この方法では動作しません。 – Artdark92

答えて

0

あなたはCMSControllerにrootScopeのプロパティの1つにナゲッジを与え、フラグを設定させることができます。また、最初のイベントを発生させてから1〜2秒間100msごとにチェックし、フラグがある場合のみ別のイベントをブロードキャストするようにrootScopeに指示することができます。

しかし、私が実際に仲介者サービスを受けることをお勧めします。通常のサービスを作成するだけでなく、代わりに通信するためにそれを使用して、ゲッターとセッターをいくつかのプライベートオブジェクトに持っています。 1つのコントローラはオブジェクトを設定し、他のコントローラはオブジェクトを準備します。この方法では、コントローラーがオブジェクトを要求しているので、コントローラーは準備が整っています。

1つのコントローラあなたの中に続いて
angular.module('app') 
    .factory('mediatorService', function() { 
     var _data= {}; 
     return { 
      //setter 
      save: function (data){ 
       _data= data; 
      }, 
      //getter 
      get: function(){ 
       return _data; 
      } 
     } 
}) 

mediatorService.save(yourobject); 

別では:私にとって

$scope.data = mediatorService.get(); 

コントローラ間のデータの通信のこの差し出される方法。あなたは、基本的には、このオプションがあります。仲介者 悪いとして

  • rootScope - 、rootscopeを汚染名 良い気を付けていない場合は別の場所でmissusedすることができます - 迅速かつほとんどのコード

  • イベント いいえ - すべての人にブロードキャストできます。あなたのようなシンクロの問題

  • ルートのparams 良い - - 迅速かつ簡単にあなたが入れ子になってしまったのコントローラ 悪い - 関与 悪い

  • クッキーと上の使用に限定されローカルストレージ いいえ - リロードを続ける必要がある場合 bad - 角度の古いブラウザの範囲外の回避策にはCookieのみがあります。役割の明確な分離とシンプルだが効果的な 悪い - - もう少しボイラーコード

  • を必要とし、ブラウザ上で防衛すると、それらはあなたが
    良い

  • メディエーターserivce に反応できずに削除される可能性があります設定します

+0

お返事ありがとうございました。残念ながら私は試してみましたが、うまくいきません。コントローラの終わりに私はmediatorServiceかどうかをチェックしています。get()は空のオブジェクトではなく、GetHelpPage関数を呼び出してページを取得しています...しかし、うまくいきません。おそらく別の問題があります... – Artdark92

+0

両方のコントローラにサービスを注入し、最初にデータを設定しましたか?おそらく、第1のセットアップの前に第2のコントローラを初期化してメディエータのデータを作成するでしょうか? – DanteTheSmith

+0

はい、すべて正常に完了しました。 最初のコントローラでは、データをメディエータサービスに設定しています。 2番目のコントローラをチェックインしています...チェックが合格です。私はコンソールです。オブジェクトにログインしていれば、それは間違いありません。私はCMSからヘルプセンターページを取得している関数にオブジェクトを渡します...結果はありません。 しかし....ここに興味深いものがあります。 $$ postDigest()コールバックが働いていたので、コントローラの読み込みが問題ではないと思っています....ダイジェストサイクルは問題ありません。私は適切な方法でその関数を実行する必要があります – Artdark92

0

2つのコントローラがあり、1つから2つ目のコントローラにイベントをブロードキャストしようとすると、完全にロードされていないのでリッスンしていません。 これを避けるには2番目のコントローラーからイベントをトリガーしてからロードした後、通常のフローを続行することができます このサンプルを見てください。それはCTRL1

この天気聞きます

(function() { 

    'use strict'; 

    appName.controller('CMSController', Controller); 
    Controller.$inject = ['$scope', '$rootScope', '$timeout', 'CONSTANTS', '$location', 'PAGE_DATA']; 

    function Controller($scope, $rootScope, $timeout) { 
     function inIt() { 
      $rootScope.$broadcast('pageLoaded'); 
     } 

     inIt(); 
    } 

}()) 

をロードされたときに CTRL2

これは、イベントをトリガする別のコントローラがロードされるか、または、この

のようにそのbroaddcastをトリガされていません
(function() { 

    'use strict'; 

    appName.controller('secCtrl', Controller); 
    Controller.$inject = ['$scope', '$rootScope', '$timeout', 'CONSTANTS', '$location', 'PAGE_DATA']; 

    function Controller($scope, $rootScope, $timeout) { 

     var pageload = 0; 
     $rootScope.$on('pageLoaded', function(event, obj) { 
      $rootScope.$broadcast('openHelpCenterPage', {slug: slug, from: 'footer'}); 
     }); 
    } 

}()) 

私はexplaを持っていますあなたの要求に応じて試してみてください。

+0

お返事ありがとうございます。問題は、その時点でCtrl 2がロードされていることです。フッターリンクを生成するには、CMSControllerが使用されます。フッタリンクをクリックした瞬間、 'pageLoaded'イベントは初期ページロード時にすでにボラードキャ​​ストされています。問題は、クリックイベントでは、Ctrl2(CMSController)が再びロードされる別のルートにリダイレクトする必要がありますが、GetHelpPages関数は以前に呼び出されている必要があります。 – Artdark92