天天看點

AngularJS中插入HTML片段

我們知道angular中預設是不信任不支援HTML内容的,是以對于要添加的

HTML 要先使用 $sce.trustAsHtml(html_in_string) 将标記為信任,然後使用 data-ng-bind-html="html_in_string" 取消轉義才能使用。

js

.controller('ModalWithSelectCtrl', function($scope,$sce) {
       $scope.modalBody=$sce.trustAsHtml("<h1>2222</h1>")
    })
           

html

<div  data-ng-bind-html="modalBody"></div>
           

對于純html來說,這個插入就完成了。

但對于複雜的html,比如是帶有angular表達式,指令的html,

因為ng-bind-html并不會和$scope産生關系的,

如果在htm中存在ng-show,ng-href...這些angular指令,它們就不會被compile也就不會有任何反應了,綁定的表達式不會被更新而直接顯示出來。

我們知道,在angular中所有指令要生效,都需要經過compile,在compile中包含了pre-link和post-link,連結上特定的行為,才能工作。

大部分complie都會在angular啟動時候,自動compile的,

但如果是對于動态添加的模闆,則需要我們手動compile了。

angular已經為我們提供了$compile服務來實作。

下面我們修改上述例子

htm

<dy-compile    html="{{modalBody}}"></dy-compile>
           

js

$scope.modalBody=$sce.trustAsHtml('<p  ng-show="is_no_user">please select user</p> <p ng-show="is_has_user"><b class="font_color" >{{selectNum}}</b> users have been selected<br>these users Click on OK to<b class="font_color ml5" >{{selectAction}}</b></p>')
           

下面這個就是我們用來手動compile的directive

.directive("dyCompile", ["$compile", function($compile) {
        return {
            replace: true,
            restrict: 'EA',
            link: function(scope, elm, iAttrs) {
                var DUMMY_SCOPE = {
                        $destroy: angular.noop
                    },
                    root = elm,
                    childScope,
                    destroyChildScope = function() {
                        (childScope || DUMMY_SCOPE).$destroy();
                    };

                iAttrs.$observe("html", function(html) {
                    if (html) {
                        destroyChildScope();
                        childScope = scope.$new(false);
                        var content = $compile(html)(childScope);
                        root.replaceWith(content);
                        root = content;
                    }

                    scope.$on("$destroy", destroyChildScope);
                });
            }
        };
    }])
           

這裡建立了一個叫dy-compile的指令,它首先會監聽綁定屬性html值的變化,當html内容存在的時候,它會嘗試首先創個一個子scope,然後利用$compile服務來動态連接配接傳入的html,并替換掉目前DOM節點;這裡建立子scope的原因,是友善在每次銷毀DOM的時,也能容易的銷毀掉scope,去掉HTML compile帶來的watchers函數,并在最後的父scope銷毀的時候,也會嘗試銷毀該scope。

因為有了上邊的compile的編譯和連接配接,則ng-show指令就可以生效了。這裡隻是嘗試給出動态compile angular子產品的例子,具體的實作方式,請參照你的業務來聲明特定的directive。