2013-02-13 7 views
29

要素内に角度jsのテンプレート文字列を挿入しようとしています。しかし、それは起こっていない。要素の内側に角度の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>'; 
} 

ouputをちょうど{{each}}です。

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

私はfiddleを作成しました。

+3

なぜコントローラからHTMLを生成していますか? –

+0

これをすべて手に入れましたか? –

+0

この問題の私の使用例:Angularスコープの変更に反応するいくつかのコントロールを挿入するサードパーティのライブラリ(リーフレット)を使用しています。私はバニラDOM APIを使って要素を作成し、 '$ scope。$ observe'を使って要素を作成することを避けたいと思います。これは基本的には通常のイベントリスナを登録するのと同じことです。 – fredrikekelund

答えて

95

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

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>'; 
    }; 
}); 

が次にあなたが読み込み、単純な指示を作成

サービスから来ていますコンパイルしてディスプレイに追加します。

0123あなたのビューから
.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:これはあなたのテンプレートがサーバーから来たものとみなされます。そうでない場合は、テンプレートがディレクティブに含まれている必要があります。

+0

ユーザーが要素をクリックすると、そのページにリスト(私の質問に同じリストテンプレート)を挿入したいと思います。コントローラでDOM操作を行わずにこのユースケースを処理できますか? – rajkamal

+0

+ rajkamal絶対に!だから私はより具体的なコードで私の答えを更新することができますクリックした要素は、ものが挿入されているものと同じですか?それは別のものですか? –

+0

その別のもの.. – rajkamal

関連する問題