30

現時点では、サイドバーを持つアプリがあり、サイドバーはng-include、ユーザーが選択した操作に基づいて、さまざまな html テンプレートを読み込みます。これはマップ関連のアプリです。たとえば、ユーザーが [脚を追加] ボタンを選択すると、次add_leg.htmlを使用してテンプレートがサイドバーに読み込まれng-includeます。

// The Javascript code:
$scope.addLeg = function() {
    $scope.sidebar = true;
    $scope.sidebar_template = '/partials/legs/add_leg.html';    
}

// Simplified example of HTML:
<html>
<div ng-app="MyApp" ng-controller="MainCtrl">
    <a ng-click="addLeg()">Add Leg</a>
    <a ng-click="addRoute()">Add Route</a>
    <a ng-click="editLeg()">Edit Leg</a>
    <a ng-click="editRoute()">Edit Route</a>
    ...

    <div id="sidebar" ng-class="{'sidebar-hidden': sidebar == false}">
        <div ng-include src="sidebar_template"></div>
    </div>

    <google-map></google-map>
</div>

これはすべて順調で、希望どおりに機能しますが、現時点では、私のアプリは 1 つのコントローラー ( MainCtrlin js/controllers.js) しか使用しておらず、本当に雑然とし始めています。アプリの機能が拡張されているため、メソッドがたくさんあります。このサイドバー機能を維持しながら、コントローラーを複数のコントローラーに分割したいと考えています。

MainCtrlサイドバー テンプレートの読み込みを制御するメイン コントローラーとして (sidebar_templateファイルの宛先を指す変数を変更することにより)、グローバル マップに関連するメソッドの一部を制御したいと考えています (座標から郊外の名前を取得するなど) 。等)。

私はそれを次のように分割しようとしました:

controllers/js/main.js - MainCtrl
controllers/js/legs.js - LegCtrl
controllers/js/routes.js - RouteCtrl

LegCtrlRouteCtrlを継承して、MainCtrlそのスコープとメソッドにアクセスできるようにしたいのですが、それで問題ありません。しかし、問題は、必要な機能に基づいて、コントローラーをサイドバー div に動的にロードする方法です。もともと私のメソッドはすべて にあり、MainCtrlそれはサイドバー div を囲むラッパー div にあったため (例については上記をもう一度参照してください)、問題はありませんでした。

たとえば、「Add Leg」ボタンを押すと、 を呼び出す必要がありますがaddLeg、アプリにロードされていないため、メソッドにアクセスできません。内に保持し、変数を変更してテンプレートをロードすることもできますが、現在内からメソッドを呼び出しているため、テンプレート内の何も機能しません。LegCtrlLegCtrladdLeg()MainCtrlsidebar_templateLegCtrl

ng-includeおそらく次のように、サイドバーの div にコントローラーを動的にロードする必要があります。

// MainCtrl
$scope.addLeg = function() {
    $scope.required_controller = LegCtrl;

    $scope.sidebar = true;
    $scope.sidebar_template = '/partials/legs/add_leg.html';    

    LegCtrl.addLeg();
}

<div id="sidebar" ng-class="{'sidebar-hidden': sidebar == false}">
    <div ng-include src="sidebar_template" ng-controller="{{required_controller}}"></div>
</div>

上記の動作しない例では、私が考えた可能な解決策を見ることができますが、LegCtrl(動作するための) オブジェクトではなく、実際のコントローラー関数である必要がありますng-controller。から呼び出す方法も必要です (おそらくブロードキャストを使用しますか?) addLegLegCtrlMainCtrl.addLeg

誰かが私を正しい方向に向けることができれば、それは素晴らしいことです. 巨大な投稿で申し訳ありません。一貫性を持たせるために少し説明が必要でした。うまくいけば、それは理にかなっています。ありがとう。

更新:サービスを使用してナビゲーション コントロールとして機能するソリューションを見つけたと思います (関連するテンプレートを読み込み、動的に読み込まれる新しいコントローラーにイベントをブロードキャストして、実行する関数を伝えます)。

http://plnkr.co/edit/Tjyn1OiVvToNntPBoH58?p=preview

今このアイデアをテストしようとしていますが、ブロードキャスト.onは機能しません。テンプレートが読み込まれる前にブロードキャストが発火するためだと思います。どうすればこれを修正できますか? これは私がやっていることの良い解決策ですか?

4

3 に答える 3

5

私はこのデータ ドリブン シナリオが好きです。テンプレートの行を操作するだけです。

$scope.templates = [
    { name: 'include1.html', url: 'partials/include1.html' }
];
$scope.addTemplate = function(name, url) {
    $scope.templates.push({ name: name, url: url });
};

およびマークアップ:

<div ng-repeat="template in templates" ng-include="template.url"></div>

ビューを追加または削除するには、テンプレートを変更するだけです。さらにコントローラー コードが必要な場合は、インクルードにスクリプトへのリンクを含めることができます。部分ビュー自体のデータへのバインドには複雑さが伴う可能性があると思いますが、 $compile はそれらを解決するはずです。

于 2014-07-04T15:39:05.377 に答える
4

あなたの plunkr デモを、あなたが探しているものを実行できると信じているものにフォークしました: http://plnkr.co/edit/whsjBT?p=preview

LegCtrlこれは、2 番目のコントローラー (この例では) がロードされng-include、データが渡された後に、あるコントローラーから別のコントローラーにイベントがブロードキャストされることを示しています。

$includeContentLoadedイベントからのイベントを使用しng-includeて、角度レポートadd_leg.htmlがロードされるまでイベントのブロードキャストを遅らせました。また、使用方法に問題があったと思います...最初のパラメーターは、で使用され$broadcast()ているものと同じである必要があります$on()LegCtrl

考慮すべきもう 1 つのアイデアはNavigation、シナリオで適切な場合は、単にサービス自体を使用してコントローラー間で状態を共有することです。

于 2013-08-03T08:09:06.577 に答える