我有一个自定义元素指令(restrict: "E"
),它用一个取决于范围的新元素替换自定义元素(通过处理link
)。这工作正常,但ngRepeat
无法删除此类指令。它似乎无法找到目标DOM元素,因为它已被指令本身取代。
代码:
<body ng-app="app">
<div ng-controller="controller">
<h3>Click an element to remove it</h3>
<custom ng-repeat="tag in tags" ng-click="remove(tag)"></custom>
</div>
<script>
angular.module("app", []).controller("controller", function($scope) {
$scope.tags = [
{ tagName: "button", text: "button" },
{ tagName: "div", text: "div" },
{ tagName: "span", text: "span" }
];
$scope.remove = function(tag) {
console.log("remove", tag.text);
$scope.tags.splice($scope.tags.indexOf(tag), 1);
}
}).directive("custom", function($compile) {
return {
restrict: "E",
link: function(scope, element, attr) {
var tag = angular.element("<" + scope.tag.tagName + ">").text(scope.tag.text);
tag.attr("ng-click", attr.ngClick)
$compile(tag)(scope);
element.replaceWith(tag);
}
}
});
</script>
</body>
Live demo(尝试点击button
,然后div
- 按钮首先不会消失,然后div和按钮都会消失)。如果我使用element.replaceWith(tag)
代替element.append(tag)
,它就可以使用。
这可以以某种方式工作吗?我需要该指令具有取决于范围的自定义标记名称,并且在删除项目时也使用ngRepeat。长话短说我不需要DOM中的<custom>
元素,因为我无法控制CSS规则。 replace:true
之类的内容适用于link
。
答案 0 :(得分:1)
要回答我自己的问题,是的,有可能使用transclude: 'element'
。然后angular给link
函数一个注释DOM元素,稍后它用于DOM操作。以下是相关代码:
return {
restrict: "E",
transclude: "element",
link: function(scope, element, attr) {
var tag = angular.element("<" + scope.tag.tagName + ">").text(scope.tag.text);
tag.attr("ng-click", attr.ngClick)
$compile(tag)(scope);
element.after(tag); // insert after the comment node
}
答案 1 :(得分:0)
为什么需要更换?
element.append(tag);
似乎work ok:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.11/angular.js" data-semver="1.3.11"></script>
<script src="app.js"></script>
</head>
<body ng-app="app">
<div ng-controller="controller">
<h3>Click an element to remove it</h3>
<custom ng-repeat="tag in tags" ng-click="remove(tag)"></custom>
<br><br>{{tags}}
</div>
<script>
angular.module("app", []).controller("controller", function($scope) {
$scope.tags = [
{ tagName: "button", text: "button" },
{ tagName: "div", text: "div" },
{ tagName: "span", text: "span" }
];
$scope.remove = function(tag) {
console.log("remove", tag.text);
$scope.tags.splice($scope.tags.indexOf(tag), 1);
}
}).directive("custom", function($compile) {
return {
restrict: "E",
link: function(scope, element, attr) {
var tag = angular.element("<" + scope.tag.tagName + ">").text(scope.tag.text);
tag.attr("ng-click", attr.ngClick)
$compile(tag)(scope);
element.append(tag);
}
}
});
</script>
</body>
</html>