2012-10-20 5 views
6

をコンパイルし、弊社のWebアプリケーションは、我々のアプリケーションのモジュール性を高めるために、別々の部分ページに整理するかもしれません。いくつかのケースでXHRやAjaxリクエストによってロードされた部分的なページをコンパイルするのいずれか$ http.get角度やjQueryの$の.LOADを使用すると、エラーをご紹介します。角度で部分的にページをロードし、大規模なアプリケーションのコントローラ

私は、サーバーレベルで私のWebアプリケーションのモジュール性を制御することができるように正確に私はKohanaのPHPフレームワークを使用しています、一例として、私のシナリオを使用します。いつものように、すべてのテンプレートとページは別々に表示され、プレゼンテーション層にすべてのHTML、JS、およびCSSが残されています。

これは、Webアプリケーションがバックエンドアプリケーションからデータを取得するAJAX要求に大きく依存するため、クライアント側の処理でJavascript MVW/MVCスタックを実装するための大きな柔軟性を提供します。私のシナリオでは、AngularJSを使用して、以下は、Modelからクライアントに提示されるデータの単純な疑似です。

Kohanaのモデル> Kohanaのコントローラ> Kohanaの表示> XHR> jQueryの\アンギュラ> DOM本当に私は私がに代謝飲み物のいくつかのボトルを飲むバンプとget与える私のアプリケーションでの私の部分の

ワンアプリケーションを解決する。私はモーダルダイアログを持っていて、部分ページはサーバからXHRを介してロードされ、選択されたDOMにアタッチされます。角度は、それが処理されたディレクティブを参照する機能を探していますNG-コントローラディレクティブを見つけたとき、部分的なページをコンパイルしようとすると

問題があります。エラーは、DOMパーサによってまだ評価されていないコントローラが見つからない場合に発生します。しかし、部分ページをロードする直前に、アプリケーションのどこかで関数を事前定義しておくと、すべてがOKです。以下は、上記のリンクをクリックしたときにlinkディレクティブから呼び出されるDialogサービスをセットアップする方法の例です。

いくつかの調査の後、私はいくつかの解決策を見つけて、私のような初心者のために私の答えを友達と共有しました。 (私の英語は申し訳ありません)。この設定でAngularJSに何も悪いことはありません

答えて

5

、他人そこJSは教祖が既に解決策を知っているし、別のクールなWeb開発ツールやフレームワークを発明しながら、私たちと共有することは非常に忙しいかもしれません。それは大丈夫です。これはクールでも最終的な解決策ではないかもしれないので、改善やヒントを教えてください!

我々はセットアップにsの戦略を必要とするこの問題を克服するために、私は情報が流れる間、そう、私たちの脳は消化するサンプルコードから始めましょう。以下のコードは、JQueryを使用してモーダルダイアログを作成し、Ajaxコンテンツを挿入するプレースホルダです。

<div ng-app="asng" id="dialog" title="" style="display:none"> 
    <div id="dialog-content"></div> 
</div> 

基本的な知識として、DOMパーサーがどのように動作しているかを理解する必要があります。私たちはDOMP(DOM Parser)がマルチスレッドであると考えているかもしれません。それが複数の外部リソースを並行してロードできる理由です。実際には、DOM要素のインデックスを上から下に解析しながら、DOMPはシングルスレッド化されています。以下は、#dialog-content DIV要素にロードする部分ページの例です。我々だけでNG-コントローラディレクティブを持つ要素の前にスクリプトブロックを置いているが

<script language="JavaScript" type="text/javascript"> 
    function Transaction ($scope,$http){ 
     $scope.items = [{"country":"VN","quantity":"100"}]; 
     $scope.country_name = $scope.items; 
    } 
</script> 

<style> 
</style> 

<div id="transaction-panel" class="user" data-ng-controller="Transaction"> 
     <form id="{{ form_name }}" action=""> 
     Country : [[ items.country ]] </br> 
     Total : [[ items.quantity ]] 
    </form> 
</div> 

実際にこれらの部分はまだ、エラーを与えます。実際にはそうではありません。私たちが取り組む必要があるのは、AngularJSコンパイルサービスが部分的なDOMをコンパイルする方法です。上記の私の質問部分に戻って、私たちがコンパイルの対象とする行を調べてみましょう。

html = $compile(data)(scope); 
$('#dialog-content').html(html); 

上記の最初の行は、データ変数にDOMをコンパイルし、そして残念ながら最初の行でエラーが叫ばれますルートDOMに挿入します:コントローラトランザクションが見つかりません。

これは、部分ページのスクリプトブロックが、ルートDOMPに挿入されていないため、DOMPパーサーによってまだ評価されていないためです。今、あなたは光OKを参照してくださいので、私たちは新しいDOMを挿入することにより、コンパイル戦略を少し変更する必要がありますし、我々は以下の挿入DOM見える例戻って解析します: - 、それを

html = $('#dialog-content').html(data); 
$compile(html)(scope); 

スリムでシンプルなソリューションをDOM解析で単純な概念を無視しているだけなので、この問題を解決するために私は午前中に頭を鳴らすことはほとんどありませんでした。

+1

私はこのアプローチを使用しようとしていますが、$ compileが定義されていないことを教えてくれます。何か別のものを追加する必要がありますか? –

+0

私はAngularJSを初期化する方法を知っておく必要があります.JsFiddleで共有できますか? – wajatimur

+0

コードサンプルはウェブサイトではっきりしていますので、 http://jsfiddle.net/9mPGB/ –

0

あなたがしようとしていることを理解していれば、ここに簡単な例があります。

私はAJAX経由でDjangoフォームに投稿し、そのページのフォームコンテンツを返されたマークアップに置き換えたいと考えました。返されたマークアップは、私はそれをロードするときに実行する必要がNG-コントローラが含まれています

.controller('MyForm', function($element, $compile, $scope){ 
    var scope = $scope; 
    var $theForm = $element; 
    var $formBlock = $element.find('.the_form'); // is replaced by the form response 
    $element.find('.submit_the_form').click(function(){ 
     // submit the form and replace contents of $formBlock 
     $.post($theForm.attr('action'), $theForm.serialize(), function(response){ 
      var newstuff = $formBlock.html(response); 
      $compile(newstuff)(scope); // loads the angular stuff in the new markup 
     }); 
    }); 
}) 

私はあなたが興味を持っている行は$(newstuff)(スコープ)をコンパイルだと思います。

EDIT: Crikeyは、今朝別のマークアップでこれを試してもうまくいきませんでした。理由は分かりません。新しいマークアップでng-modelが割り当てられたフィールドがなければ、$コンパイルは実行されないことが判明しました。加えられた:

<input type="hidden" name="dummy" value="0" ng-model="dummy"/> 

...今コンパイルします。

関連する問題