web-dev-qa-db-ja.com

ng-bind-htmlでanglejsコードをコンパイルする方法

Angularjs 1.2.0-rc.3を使用しています。 HTMLコードをテンプレートに動的に含めたいです。そのために私はコントローラーで使用します:

html = "<div>hello</div>";
$scope.unicTabContent = $sce.trustAsHtml(html);

私が得たテンプレートで:

<div id="unicTab" ng-bind-html="unicTabContent"></div>

通常のhtmlコードでは正常に機能します。しかし、angular templateを解釈しようとすると、それは解釈されず、ページに含まれるだけです。たとえば、以下を含めたいと思います。

<div ng-controller="formCtrl">
    <div ng-repeat="item in content" ng-init="init()">
    </div>
</div>

どうもありがとう

52
Clement Roblot

このソリューションはハードコーディングされたテンプレートを使用せず、Angular APIレスポンス内に埋め込まれた式をコンパイルできます。


ステップ1。このディレクティブをインストールします: https://github.com/incuna/angular-bind-html-compile

ステップ2。ディレクティブをモジュールに含めます。

angular.module("app", ["angular-bind-html-compile"])

ステップ3。テンプレートでディレクティブを使用します。

<div bind-html-compile="letterTemplate.content"></div>

結果:

コントローラーオブジェクト

 $scope.letter = { user: { name: "John"}}

JSONレスポンス

{ "letterTemplate":[
    { content: "<span>Dear {{letter.user.name}},</span>" }
]}

HTML出力=

<div bind-html-compile="letterTemplate.content"> 
   <span>Dear John,</span>
</div>

参考のために、関連するディレクティブを次に示します。

(function () {
    'use strict';

    var module = angular.module('angular-bind-html-compile', []);

    module.directive('bindHtmlCompile', ['$compile', function ($compile) {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                scope.$watch(function () {
                    return scope.$eval(attrs.bindHtmlCompile);
                }, function (value) {
                    element.html(value);
                    $compile(element.contents())(scope);
                });
            }
        };
    }]);
}());
77
Ryan.lay

これは私が作ったものです、the angular wayTM、しかしそれは機能し、とてもシンプルです;

.directive('dynamic', function($compile) {
    return {
        restrict: 'A',
        replace: true,
        link: function (scope, element, attrs) {
            scope.$watch(attrs.dynamic, function(html) {
                $compile(element.html(html).contents())(scope);
            });
        }
    };
});

そう;

<div id="unicTab" dynamic="unicTabContent"></div>

編集:angular way)が見つかりました、それはsuperシンプル。

$templateCache.put('unicTabContent', $sce.trustAsHtml(html));
<div id="unicTab" ng-include="'unicTabContent'"></div>

独自のディレクティブなどを作成する必要はありません。しかし、それはバインドのようなものです あなたのhtmlに加えられた変更を見ることはありません のように カスタムディレクティブはあります

19
Hashbrown

私は同じことをしようとしていて、このモジュールに出会いました。

http://ngmodules.org/modules/ng-html-compile

それを含めるだけで、「ng-bind-html」の代わりに「ng-html-compile」を使用できました

2
nbarth

Vinod Louisがコメントで述べているように、それを行う最善の方法はテンプレートを使用することでした。通常のコードの外部でテンプレートを定義する必要がありました。たとえば、そのコードをindex.htmlの内部に追加しました。

<script type="text/ng-template" id="unic_tab_template.html">
    <div ng-switch on="page">
        <div ng-switch-when="home"><p>{{home}}</p></div>
        <div ng-switch-when="form">
            <div ng-controller="formCtrl">
                <div ng-repeat="item in content">{{item.name}}:{{item.value}}</div>
            </div>
        </div>
        <div ng-switch-default>an error accured</div>
    </div>
</script>

このテンプレートは条件付きなので、$ scope.pageの値に応じて、3つのテンプレート(3番目はエラーハンドラー)を切り替えます。それを使用するには:

<div id="unicTab" ng-controller="unicTabCtrl">
    <div ng-include="'unic_tab_template.html'"></div>
</div>

そうすれば、unicTabCtrlコントローラー内の$ scopeに応じてページが変わります。

Anglesjsテンプレートシームを挿入するというアイデアを実現するのが難しいと結論付けるために($ compileシームは解決策ですが、私はそれを機能させることができませんでした)。ただし、代わりに条件付きテンプレートを使用できます。

2
Clement Roblot

テンプレートを使用せずに現在のアプリで同様の問題を解決する方法(エレガントではありませんが機能しています):

directive('ngBindHtmlCompile', ['$compile', function ($compile) {
    return {
        restrict: 'A',
        compile: function compile(tElement, tAttributes, transcludeFn) {
            return function postLink(scope, element, attributes) {
                scope.$watch(function() {
                    return scope.$eval(attributes.ngBindHtml);
                }, function(newValue, oldValue) {
                    $compile(element.children())(scope);
                });
            };
        }
    };
}]);

同じ要素でngBindHtmlを必要とし、ngBindHtmlで変更した後に要素の内容をコンパイルします。

<div id="unicTab" ng-bind-html="unicTabContent" ng-bind-html-compile></div>

ng-html-compileは似ていますが、一見すると、テンプレートのコンテンツが変更されたときに再計算されません。しかし、私はそれを試していません。

1

1つの方法は、angular expressionsionsを含むカスタムテンプレートを挿入する目的でディレクティブを使用することです

<div id="unicTab" unic-tab-content></div>
app.directive("unicTabContent",function(){
   return {
      restrict:"A",
      template:'{{unicTabContent}}'
   }
})
1
charlietfl

組み込みテンプレートに基づく@ clement-roblotの非常に単純化されたソリューション。

コントローラ:

app.controller('TestCtrl', [
    '$scope',
    '$templateCache',
    function ($scope, $templateCache) {
        $templateCache.put('test.html', '2 + 2 = {{ 2 + 2 }}');
    }
]);

見る:

<div ng-include="'test.html'"></div>
0
Stalinko

以下のコードは、Angularの組み込みの$ interpolateおよび$ sceオブジェクトを使用すると、はるかに簡単です。まず、ディレクティブで必要なカスタムを行うときに、$ interpolateと$ sce Angularオブジェクトをディレクティブに挿入します。

amqApp.directive('myDir', ['$interpolate', '$sce', function ($interpolate,$sce ) {...}

次に、インポートしたhtml式で見つかったスコープ変数をすべて作成します...

$scope.custom = 'Hello World';

次に、$ interpolateを使用してカスタムHTMLとその式を処理します。次に、バインドする前に$ sceオブジェクトを使用してHTMLとして信頼していることを確認してください...

var html = $interpolate('<b>{{custom}}</b>')($scope);    
$scope.data = $sce.trustAsHtml(html);

最後に、ビューで、ビュー表示で「ng-bind」または「ng-bind-html」が付いた要素を使用するようにしてください。このようにhtmlテンプレートにバインドしないと、$ sceピースはHTMLをHTMLとして表示しません(テキストとして表示します)。

<span ng-bind-html="data"></span>

太字で表示されるはずです...

Hello World

このトリックを使用して、web.configからカスタムangular {{expressions}}でtext/HTMLにインポートしました。

0
Stokely