动态加载模板会在页面上留下旧模板/范围

时间:2015-04-24 20:15:10

标签: angularjs angularjs-directive

为了AB角度测试,我们尝试动态加载和编译DOM元素。到目前为止,这段代码运行良好:

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"}

我所看到的问题是,被替换的元素仍然存在于页面上(虽然隐藏在某个地方 - 我实际上并没有看到它,但我可以找到一些调试),它导致一些内部指令失败。此外,尝试删除它或将其取消也不会产生任何影响。

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

问题在于,即使您从DOM中删除了子树,也永远不会取消注册offClick在文档上设置的点击处理程序。

具体地,

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

永远不会发射,因为范围永远不会被破坏。

使用elm.on("$destroy", ...取消注册点击处理程序:

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

关闭-主题

  1. 您确定需要在每个document的{​​{1}}上设置点击处理程序吗?如果你有两个,每个都会设置一个处理程序。

  2. 我不建议使用您自己的属性扩展offClick对象。我指的是angular