指令代码:
.directive('replace', function($compile) {
return function (scope, element) {
element.html(element.html().replace("Hej", "Hey!"));
$compile(element.contents())(scope);
}
});
})
HTML
<div ng-controller="GreeterController">
<div replace>Hej <div ng-repeat="e in arr">{{ e }}</div>
</div>
</div>
控制器
app.controller('GreeterController', ['$scope', function($scope) {
$scope.arr = [1, 2, 3, 4];
}]);
正如标题所说,当我在包含它的HTML上使用上面的指令时,ng-repeat
无法正常工作。
但是,一旦我删除了使用.replace()
命令替换部分HTML的行,那么ng-repeat
由于某种原因开始工作。
有谁知道实际问题在哪里?
我已经尝试了一切,但我似乎仍然无法理解为什么它不能正常工作。
答案 0 :(得分:0)
您应该让Angular及其更改检测周期为您执行HTML操作,而不是直接自行更改。
我已编辑您的示例以使用范围绑定来实现您想要的目标:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example - example-compile-production</title>
<script src="//code.angularjs.org/snapshot/angular.min.js"></script>
</head>
<body ng-app="compileExample">
<script>
angular.module('compileExample', [], function($compileProvider) {
// configure new 'compile' directive by passing a directive
// factory function. The factory function injects the '$compile'
$compileProvider.directive('replace', function($compile) {
return {
link: function (scope, element) {
scope.greeting = 'Hey!';
$compile(element.contents())(scope);
}
}
});
})
.controller('GreeterController', ['$scope', function($scope) {
$scope.test = [1, 2, 3, 4];
$scope.greeting = 'Hej';
}]);
</script>
<div ng-controller="GreeterController">
<div replace>{{greeting}} <div ng-repeat="e in test">{{ e }}</div></div>
</div>
</body>
</html>
<!--
Copyright 2017 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->
注意:我删除了“scope:false”,因为这是默认行为。
编辑: 既然你必须替换HTML,这里是jQuery的解决方案:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example - example-compile-production</title>
<script src="//code.angularjs.org/snapshot/angular.min.js"></script>
<script
src="https://code.jquery.com/jquery-3.1.1.min.js"
integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
crossorigin="anonymous"></script>
</head>
<body ng-app="compileExample">
<script>
angular.module('compileExample', [], function($compileProvider) {
// configure new 'compile' directive by passing a directive
// factory function. The factory function injects the '$compile'
$compileProvider.directive('replace', function($compile) {
return function (scope, element) {
$(element).find( ".translation" ).replaceWith("Hey!");
}
});
})
.controller('GreeterController', ['$scope', function($scope) {
$scope.arr = [1, 2, 3, 4];
}]);
</script>
<div ng-controller="GreeterController">
<div replace><span class="translation">Hej</span> <div ng-repeat="e in arr">{{ e }}</div></div>
</div>
</body>
</html>
<!--
Copyright 2017 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->
答案 1 :(得分:0)
解决这个问题:
.directive("replace", function(){
return {
compile: function(){
return {
pre: function(scope, element){
element.html(element.html().replace('Hej', 'Hey!'));
}
}
}
};
});
答案 2 :(得分:0)
操作也可以在编译阶段完成:
app.directive("replace", function(){
return {
compile: function(element){
element.html(element.html().replace('Hej', 'Hey!'));
/*return {
pre: function(scope, element){
element.html(element.html().replace('Hej', 'Hey!'));
}
}*/
}
};
});
原始问题是由于ng-repeat
指令的链接在具有该指令的元素被替换为替换操作之前完成的。然后,与ng-repeat
指令关联的观察者对不再附加到可见DOM的元素进行操作。
通过将替换操作移动到编译阶段或preLink阶段,在ng-repeat
指令链接之前替换具有ng-repeat
指令的元素。与ng-repeat
指令关联的观察者然后使用替换的DOM。