2016-11-24 65 views
5

背景

我需要在我AngularJS(V1.4)應用中的一些HTML從後臺得到加載和插入它(HTML)到我的partial(已經加載)。部分已經加載了一些HTML(並且功能完全)。現在,我可以加載HTML並通過在此處發佈的指令進行編譯(Compiling dynamic HTML strings from database)。見下面的代碼。

問題

可是......當HTML的一部分已經被加載(部分加載和功能),然後我從後端另一個HTML內容,以及該指令在編譯新的,整個文檔(DOM)被「凍結」。我無法輸入輸入或點擊任何按鈕,包括我之前加載的HTML中的按鈕。

問題

我怎麼能加載HTML內容,$compile它在「後臺」或者,讓我繼續使用(已功能)HTML其餘任何其他方式?

對於我來說,到達的新html內容會被編譯,因爲它包含角度驗證等,需要編譯並進入「角度世界」(在角度digest cycle等等之內) 。

這是我使用的指令編制的HTML

(function() { 

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

       }); 
      } 
     }; 
    }; 

    dynamic.$inject = ['$compile']; 

    angular.module('app') 
     .directive('dynamic', dynamic); 
}()); 

在控制器我有類似

// this will be filled with asynchronous calls were I get the HTMLs from a service 
// in order to keep this example simple I just made a demo, not with the real async calls 
$scope.secciones = [] 

//when the promises are getting resolved "secciones" would be something like (more items can be added after in time) 
$scope.secciones = [ 
    {html: "<div> some html content here (not too small sometimes) </div>"}, 
    {html: "<div> another html content here (not too small sometimes) </div>"} 
] 

..並在視圖

<!--every time an async call with html is resolved, it's added to secciones, then a new div is generated and compiled--> 
<!-- if there was some html previously rendered and the app starts compiling new html the UI gets "freezed"--> 
<div ng-repeat="item in secciones"> 
    <div dynamic="item.html"></div> 
</div> 

注:我使用這種方法,因爲每個HTML代表在一個tabpanel我有,在用戶實際只看到一個個個的HTML中的「secciones」選項卡(其他人是隱藏的,但仍然存在),但我需要編譯其他人,以便當他/她單擊其他選項卡(secionion中的另一個html)時爲用戶準備好它們。

如果可以通過升級到更新版本的AngularJS(1.x)來解決這個問題,比如1.6。我會很樂意嘗試一下。

+0

使用'$ timeout'包編譯的模板。這樣你就不會阻塞主線程,並且你的應用會有反應 – Kliment

+0

還有$ scope。$ evalAsync。參考:https://docs.angularjs.org/api/ng/type/$rootScope.Scope –

+0

謝謝你們。使用我在我的問題中提到的指示我做 '$範圍evalAsync( 函數(){ ele.html(HTML); $編譯(ele.contents())(範圍);} )。 ' 和 ' $超時(函數(){ ele.html(HTML); $編譯(ele.contents())(範圍); }) ' 行爲是相同的: ( – lealceldeiro

回答

2

基本上我通過從腳本標記獲取html並編譯它並追加到現有的div來完成此操作。 你可以使用下面的代碼片段。

包含的div在HTML

<div id="step-container"> 

</div> 

控制器代碼

var template = $templateCache.get('basicInfo'); // or your html 
$compile($("#step-container").html(template).contents())($scope); 
$("#step-container").show(); 

出於演示,這將被包含在HTML頁面

<script type="text/ng-template" id="basicInfo"></script> 

以這種方式,你可以編譯你的HTML來自後端。

希望它有幫助。

+0

只要我試一試,我會給你一些反饋。您的幫助! – lealceldeiro

+0

當然這會工作 –

+0

我一直在玩弄你的解決方案,但我想我誤解了$ templateCache.get方法的作用。我雖然會收到一些html內容(包括字符串html),但似乎只有htmll內容在一個文件中,例如它可能被傳遞給該方法。我傳遞了一個字符串,表示希望呈現的html,但$ templateCache.get方法返回undefined,請參閱我的devtools的這個屏幕截圖。 「data」是html字符串,模板是$ templateCache.get的返回請參閱https://www.dropbox.com/s/5k2m3gs56grxoqp/sample.png?dl=0 – lealceldeiro

1

您可以嘗試使用此指令來編譯HTML代碼。該指令編譯代碼時檢測可變htmlCode

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 && value.toString()); 
        var compileScope = scope; 
        if (attrs.bindHtmlScope) { 
         compileScope = scope.$eval(attrs.bindHtmlScope); 
        } 
        $compile(element.contents())(compileScope); 
       }); 
      } 
     }; 
    }]); 

您可以通過安裝鮑爾任何變化,DirectiveRepo

用法:

<div bind-html-compile="htmlCode"></div>

+0

謝謝@ Isma90的幫助。我只是試着用你的指令,但最後的結果是一樣的。當html很大時,屏幕像之前一樣凍結。 – lealceldeiro