2012-11-24 54 views
29

フロントエンドのバックエンドからAngularJSに値を渡す最も良い方法は何ですか?私はDjangoを使用しており、テンプレートは必要な値を吐き出すことができますが、これらの値をAngularJSに渡す際のベストプラクティスは不明です。AngularJS - バックエンドからフロントエンドへの値の受け渡し

ブログの投稿とそのコメントを考えてください。投稿IDをサービスに渡して特定のブログ投稿のすべてのコメントを取得するAngularJSサービスがあり、DjangoがHTMLテンプレートをレンダリングしていて、ポストIDですが、私はこのポストIDをAngularJSに渡し、その後にサービスに渡す必要があります。

1つのアイデアは、それを隠した<input>に入れ、この入力をモデルに割り当てることです。あまり魅力的ではありません。

// Django (or any backend) is rendering {{ object.value }} 
<div class="myDirective" data-object-id={{ object.value }}> 
    ... 
</div> 

angular.module('myDirectives', []). 
    directive('myDirective', function() { 
     return { 
      restrict: 'C', 
      transclude: false, 
      link: function postLink($scope, $element, $attrs) { 
       // $attrs.objectId would have the value 
      } 
     } 
    }); 

これらの2つのアプローチがうまく見える:

もう一つは、私がこの属性の値にアクセスすることができるだろう、このようにディレクティブを持っており、このディレクティブに属性にこの値を渡すことです。しかし、私はこれを行うよりクリーンな方法があるのだろうかと思っていますか? AngularJSのベストプラクティスに従うアプローチはありますか?

答えて

22

ビューからモデル値のほんの一握りを初期化する必要がある場合ng-initディレクティブは、あなたが探しているものかもしれません:あなたは、単に書くことができ、それを使用してhttp://docs.angularjs.org/api/ng.directive:ngInit

<div ng-init="myModel=backend-generated-value-here"> 
    ... 
</div> 

は言いましたAngularJSはWeb2.0のフルクライアント側のWebアプリケーションに焦点を当てているため、上の例では、使用例のベストプラクティスを見つけるのに苦労するかもしれません。現時点では、サーバー側でコンテンツを生成するのが理想的です。 AngularJSの将来のバージョンでは変更される可能性があります。

+2

ありがとうございます。バックエンド(Django)が純粋に残りのAPIを提供している間に、私のアプリケーションの約90%がクライアント側に変換されていると言えます。 – abstractpaper

+0

ドキュメントによれば、ng-initはng-repeatでのみ適切です。より良い方法は、htmlからコントローラにデータを渡すカスタムディレクティブを作成することです。 – Charlesthk

+0

DjangoコンパイラとAngularJSの両方がこのソリューションでどのように動作するのか不思議です...彼らは一度に同じコード領域を読んでいると思いますか? – Ricardo

9

必要なのは、特定の「ページ」(ビューへのバックエンド呼び出し)の初期値を設定するだけで、実証済みのように行うことができます。

// Django (or any backend) is rendering {{ object.value }} 
<script> 
    var backendVars = { 
    {{object.name}} : {{object.value}} 
    //and any other objects, manually parsed 
    } 
</script> 

そして、ブートストラッププロセス上の角度でそれを読んで:私はそうのように、JavaScriptでグローバル変数を設定することにより、それを「きれい」になるだろう。

しかし、angularJSは独自のMVCであるため、必ずしもページ全体をリロードする必要はなく、データまたはバックエンドコントローラのプロセスを設定/取得できます。 「クリーン」な方法は、あなたが(つまりJSONを返すビュー、例えば)必要なデータを返し、$ httpまたは$リソースサービスを経由して、それを取得するために、Webサービスを作るために、その後です:

angular.module('myApp', []). 
    controller('MainCtrl', function($scope, $html) { 
    $html({ 
    method: 'GET', 
    url: '/your/JSON/view.json' 
     }). 
     success(function(data, status){ 
     $scope.yourData = data; 
     }). 
     error(function(data, status){ 
     //whatever you need to do if the data is not available 
     }); 
    } 

また、Iディレクティブに直接データやロジックを置くべきではないことに注意してください。ディレクティブはDOM操作のためのものです。コントローラの情報を取得し、スコープの継承、属性、双方向データバインディングを介してディレクティブに渡してください。それが役に立てば幸い。

+0

バックエンドが渡している値に依存するため、Webサービスを呼び出すことができません。ブログ記事とこのブログ記事を表示するビューについて考えてみましょう。このブログ投稿情報を返すAPIがあれば、データを取得するために投稿IDをWebサービスに渡す必要があります。 – abstractpaper

+1

答えの最初の部分はあなたが求めていたものです。 しかし、これは「心配」ではありません.jQueryやモデル指向のような、より小さなツールベルトのようなフレームワークの仕事をするためには、大きな(そして大量に構造化された)MVCフレームワークを使用しています。 角度では、あなたはこれを次のように考えます:you.com/blog/123に電話して、毎回異なるページでアプリをブートストラップし、you.com/#/blog/123に電話して$ルートと$ htmlを使用できるあなたはビューを変更すると、ブログのコンテンツを取得し、決してページ(アプリ)から離れることはありませんか? ブログのようなものであれば、角度は最良の選択ではないかもしれません。 –

+0

ポイントがあります。私はむしろ地球規模の名前空間を汚染しないだろう、私は可能な限りグローバル変数を避けようとしている。あなたの答えをありがとう、私は言及した2つのアプローチに行くか、説明された@ pkozlowski.opensourceとして 'ng-init'を使用します。 – abstractpaper

9

これを行う適切な方法は、サーバがvalue providerのスクリプトをレンダリングしてから、それをあなたのアプリに依存して挿入することです。そのような:

のindex.php:

<html ng-app='myApp'> 

<head> 
    <title>AngularJS Back to Front</title> 
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.min.js"></script> 
    <script src='index.js'></script> 
    <?php 
     $globals = array(
      'count' => 1, 
      'title' => 'Active users', 
      'users' => array(
       'name' => 'john', 
       'age' => 21 
      ) 
     ); 

     $globalsJSON = json_encode($globals) 
    ?> 

    <script> 
     myApp.value('globals', <?=$globalsJSON;?>); 
    </script> 
</head> 

<body ng-controller="myController"> 
    <div>{{title}}</div> 
</body> 

</html> 

インデックス。js:

var myApp = angular.module('myApp', []); 

myApp.controller('myController', [ 'globals', '$scope', function(globals, $scope) { 
    // Copy globals to scope 
    for (var property in globals) { 
     $scope[ property ] = globals[ property ]; 
    } 
}]); 
+0

すでに複雑なsitutationにphpを追加しても、私にとってはうまく見えません。 –

関連する問題