无法修改动态渲染元素的className?Angular动态指令问题及解决
分享一次Angular动态DOM修改失效的排查与解决
最近碰到个头疼的问题:我想给div#programmationEtat的第一个子元素加上active类,HTML结构大概是这样:
<div id="programmationEtat"> <div class="tab-pane ng-scope">...</div> <div class="tab-pane ng-scope">...</div> ... </div>
我先用原生JS写了修改逻辑:
var children = document.getElementById("programmationEtat").children; console.log(children); children[0].className = 'active'; console.log(children);
奇怪的是,控制台输出明明显示第一次子元素class是tab-pane ng-scope,第二次变成了active,但Chrome调试器里的HTML完全没变化,class还是原来的样子。
排查过程
折腾了半天,才发现问题出在项目里的一个自定义dynamic指令上。这个指令是用来动态编译渲染HTML的,代码如下:
app.directive('dynamic', ['$compile', function ($compile) { return { restrict: 'A', replace: true, link: function (scope, ele, attrs) { scope.$watch(attrs.dynamic, function (html) { ele.html(html); $compile(ele.contents())(scope); }); } }; }]);
这个指令会监听$scope.programmation变量,一旦它更新就重新编译渲染对应的HTML片段。而我要修改的div#programmationEtat正好就包含在$scope.programmation的字符串里!
原来如此——我手动用原生JS修改DOM后,指令在后续的渲染周期里又把整个HTML片段重新生成了一遍,直接覆盖了我修改的内容,所以调试器里看不到变化。
解决方法
既然DOM是从$scope.programmation动态生成的,那直接改DOM肯定行不通,得从数据源本身下手。我用字符串替换的方法,直接修改$scope.programmation里的内容:
// 替换第一个出现的目标class,添加active $scope.programmation = $scope.programmation.replace( '<div class="tab-pane ng-scope">', '<div class="tab-pane ng-scope active">' );
这样一来,当dynamic指令重新渲染HTML时,第一个子元素的class就会自动带上active,而且不会被后续的渲染覆盖了。
内容的提问来源于stack exchange,提问作者C.Norris
相关产品推荐
相关产品推荐

