angularjs – 如何删除由使用$compile动态添加和删除的模板创建
发布时间:2020-12-17 17:20:57 所属栏目:安全 来源:网络整理
导读:我们有这个指令允许开发人员使用$compile指定他们自己的模板和数据,这些模板和数据将用于将绑定到该模板的作用域.模板可能会有角度表达式,这将创建观察者. 当从DOM树中删除由模板和范围表示的元素内容时,如何删除使用它创建的观察者? 这个link证明了即使当
我们有这个指令允许开发人员使用$compile指定他们自己的模板和数据,这些模板和数据将用于将绑定到该模板的作用域.模板可能会有角度表达式,这将创建观察者.
当从DOM树中删除由模板和范围表示的元素内容时,如何删除使用它创建的观察者? 这个link证明了即使当它所代表的DOM从树中移除时,观察者也会留下来. 第一次单击编译按钮将编译角度模板并将其附加到DOM树.第二次单击该按钮时,它将清空添加了上一个模板的元素并添加新编译的模板. 的index.html <!DOCTYPE html> <html ng-app="app"> <head> <script data-require="jquery@1.7.2" data-semver="1.7.2" src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script data-require="angular.js@1.2.6" data-semver="1.2.6" src="https://code.angularjs.org/1.2.6/angular.js"></script> <link rel="stylesheet" href="style.css" /> <script src="smart-table-debug.js"></script> <script src="script.js"></script> </head> <body ng-controller="controller"> <h1>Compile Demo</h1> HTML to compile<br/> <textarea id="html" ng-model="html"></textarea> <br/> Result<br/> <div id="result"></div> <br/> <input type="button" value="compile" ng-click="compile()" /> <br/> Compile time: {{ compileTime }}<br/> Watchers count: {{ watchersCount }}<br/> Digest count: {{ digestCount }} <br/> Total time taken: {{ totalTime }} milliseconds <br/> </body> </html> 的script.js function getAllScopes( rootScope,allScopes ) { if( !allScopes ) { allScopes = []; } allScopes.push( rootScope ); for( var scope = rootScope.$$childHead; scope; scope = scope.$$nextSibling ) { getAllScopes( scope,allScopes ); } return allScopes; } angular.module( "app",[] ) .controller( "controller",["$scope","$compile","$rootScope","$timeout",function($scope,$compile,$rootScope,$timeout ){ var e = angular.element; $scope.html = "<div>{{watchersCount}}</div>" $scope.watchersCount = 0; $scope.digestCount = 0; $scope.compileClickStart = performance.now(); $scope.totalTime = 0; /* because we didn't gave watch expression as 1st parameter but a functionn,* the function will be called at every end of digest cycle. * https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest */ $rootScope.$watch(function() { $scope.digestCount += 1; $scope.totalTime = performance.now() - $scope.compileClickStart; }); $scope.compile = function(){ $scope.digestCount = 0; $scope.compileClickStart = performance.now(); var insertTarget = e('#result'); var targetScope = $scope.$new(); insertTarget.empty(); t0 = performance.now(); var expandedContent = $compile($scope.html)(targetScope); t1 = performance.now(); $scope.compileTime = (t1 - t0) + " milliseconds."; insertTarget.append( expandedContent ); $timeout( function() { var allScopes = getAllScopes($rootScope); var allWatchers = []; for( var i = 0; i < allScopes.length; i++ ) { var scope = allScopes[i]; if( scope.$$watchers) { //allWatchers = allWatchers.concat( scope.$$watchers ); for( var j = 0; j < scope.$$watchers.length; j++ ) { allWatchers.push({ "scope" : scope,"watcher" : scope.$$watchers[j] }); } } } console.log( allScopes ); $scope.watchersCount = allWatchers.length; }); }; }]); 解决方法
如TGH所述,观察者通常在其所在的DOM和范围被破坏时被移除.如果您没有这样做,那么您可以获得对元素范围的引用并手动销毁范围,从而删除观察者.
为简洁起见,省略了不相关的代码. var expandedContent; $scope.compile = function(){ // ... var insertTarget = e('#result'); var targetScope = $scope.$new(); if (expandedContent) { expandedContent.scope().$destroy(); } insertTarget.empty(); expandedContent = $compile($scope.html)(targetScope); insertTarget.append( expandedContent ); // ... } 如果您已经在指令中使用了此功能,则在链接功能中完成后会更加清晰.侦听元素从DOM中删除并相应地清理范围. link: function (scope,element,attrs) { element.on("$destroy",function () { scope.$destroy(); }) } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |