30

Angular jsテンプレート文字列を要素内に配置しようとしていますが、コンパイルされた出力を期待しています。しかし、それは起こっていません。

HTML

<div ng-controller="testController">
    <div ng-bind-html-unsafe="fruitsView"></div>
</div>

コントローラ:

function filterController($scope){
    ...
    $scope.arr = ["APPLE", "BANANA"];
    $scope.fruitsView = '<div><p ng-repeat="each in arr">{{each}}</p></div>';
}

出力はただ{{each}}です。

では、Angular jsテンプレート文字列(ここ$scope.fruitsView)を要素内に挿入するにはどうすればよいですか?

私はこれをいじくりまわしました。

4

1 に答える 1

95

この場合、単に「HTMLを挿入」するのではなく、コンパイルします。このサービスを使用してDOMノードを作成できます$compile

var tpl = $compile( '<div><p ng-repeat="each in arr">{{each}}</p></div>' )( scope );

ご覧のとおり$compile、スコープオブジェクトをパラメーターとして受け取る関数を返します。これに対して、コードが評価されます。element.append()結果のコンテンツは、たとえば、を使用してDOMに挿入できます。

重要な注意:ただし、どのような状況でも、DOM関連のコードはコントローラーに属していません。適切な場所は常に指示です。このコードはディレクティブに簡単にスローできますが、なぜプログラムでHTMLを挿入しているのでしょうか。

より具体的な回答を提供できるように、ここでいくつかの光を当てることができますか?

アップデート

データがサービスからのものであると仮定すると、次のようになります。

.factory( 'myDataService', function () {
  return function () {
    // obviously would be $http
    return [ "Apple", "Banana", "Orange" ];
  };
});

そして、あなたのテンプレートはサービスから来ています

.factory( 'myTplService', function () {
  return function () {
    // obviously would be $http
    return '<div><p ng-repeat="item in items">{{item}}</p></div>';
  };
});

次に、提供されたテンプレートを読み取り、コンパイルして、ディスプレイに追加する単純なディレクティブを作成します。

.directive( 'showData', function ( $compile ) {
  return {
    scope: true,
    link: function ( scope, element, attrs ) {
      var el;

      attrs.$observe( 'template', function ( tpl ) {
        if ( angular.isDefined( tpl ) ) {
          // compile the provided template against the current scope
          el = $compile( tpl )( scope );

          // stupid way of emptying the element
          element.html("");

          // add the template content
          element.append( el );
        }
      });
    }
  };
});

次に、あなたの視点から:

<div ng-controller="MyCtrl">
   <button ng-click="showContent()">Show the Content</button>
   <div show-data template="{{template}}"></div>
</div>

そして、コントローラーでは、単にそれを結び付けるだけです。

.controller( 'MyCtrl', function ( $scope, myDataService, myTplService ) {
  $scope.showContent = function () {
    $scope.items = myDataService(); // <- should be communicated to directive better
    $scope.template = myTplService();
  };
});

そして、それはすべて一緒に機能するはずです!

PS:これはすべて、テンプレートがサーバーからのものであると想定しています。そうでない場合は、テンプレートをディレクティブに含める必要があります。これにより、作業が簡素化されます。

于 2013-02-13T05:29:31.543 に答える