2015-04-24 32 views
0

我們正在嘗試動態加載和編譯DOM元素,以便進行AB測試。到目前爲止,該代碼工作得很好:動態加載模板會在頁面上留下舊的模板/範圍

MyApp.directive('testing', 
['$http', '$templateCache', '$compile', '$window', 
function($http, $templateCache, $compile, $window) { 
    return { 
     restrict: 'A', 
     compile: function(tElement, tAttrs, transclude) { 
      return { 
       pre: function(scope , elm, iAttrs) { 
        var test = iAttrs.testing 

        //Ensure the test is in place 
        if (typeof angular.testing[test]== "undefined" || !angular.testing[test].template) 
         return false; 

        //Build the template path 
        var tmpName = "/angular/app/testing/"+test+"/"+angular.testing[test].template+".html" 

        //Hide the original template so the change doesn't flash 
        angular.element(elm).css('display', 'none') 

        //Retrieve the new template 
        $http.get(tmpName, {cache: $templateCache}).success(function(tplContent){ 
         //Compile it 
         var compiled = $compile(tplContent)(scope) 
         //Replace the element with the new compiled template 
         elm.replaceWith(compiled) 
        }) 
       } 
      } 
     } 
    }  
}]) 

然後,可以將它放在這樣的事情:

<div testing="mytest"></div> 

而且您的測試軟件可以與一些設置變化這樣

angular.testing.mytest = {template: "newtest"} 

我看到的問題是,被替換的元素仍然存在於頁面上(雖然隱藏在某處 - 我實際上沒有看到它,但我可以通過一些調試找到它),並且它導致一些實習生al指令失敗。另外,試圖刪除它或將其歸零不會產生任何影響。

有什麼建議嗎?

+0

請在plunker中重現此操作。我不確定這是什麼意思,元素「隱藏在某處......但我可以通過一些調試找到它」。另外,什麼是「原始模板」? –

+0

@NewDev這是一個plunkr:http://plnkr.co/edit/YtQknR3FXaxKwhfXXKCO?p=preview。要查看我在說什麼,請打開控制檯並單擊「新建」 - 應該只有一個元素觸發脫機單擊插件,但原始元素也會觸發。這是我的問題的根源。 –

回答

1

問題是,即使您從DOM中刪除子樹,也不會取消註冊offClick在文檔上設置的點擊處理程序。

具體地說,

scope.$on("$destroy", ...) 

永遠不會觸發,因爲範圍從不破壞。

使用,相反,elm.on("$destroy", ...取消註冊單擊處理:

elm.on("$destroy", function(){ 
    $document.off('click', handler); 
}); 

題外話

  1. 你確定你需要設置上單擊處理document每個offClick?如果你有兩個,每個都會設置一個處理程序。

  2. 我不建議使用您自己的屬性來擴展angular對象。我指的是angular.testing = {}

+0

巨大!這工作。這個元素儘管被替換仍然存在,這看起來很奇怪。謝謝。 –