replace,是否替换掉自定义的指令, 默认是false
Element形式
<!DOCTYPE html>
<html><head>
<Meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="stylesheet" href="bootstrap.min.css">
<script src="jquery.min.js"></script>
<script src="angular.min.js"></script>
<script src="bootstrap.min.js"></script>
<script type="text/javascript">
var app = angular.module('myapp',[]);
app.directive('cust',function(){
return {
restrict: 'EA',
template:"<span>hello</span>"
}
});
</script>
<style type="text/css">
</style>
</head>
<body ng-app="myapp">
<cust></cust>
</body>
</html>
可以看到cust指令还保留在html里,模板中的内容包含在其中.
attribute形式
<body ng-app="myapp">
<div cust></div>
</body>
可以看到div还保留在html中.
replace:true
Element形式
可以看到,<cust></cust>不见了.
Attribute形式
div不见了替换为span,但是span中有cust属性.
默认是false
<html>
<head>
<Meta name="viewport" content="width=device-width,
replace: true,
template:"<div>world</div>"
}
});
</script>
<style type="text/css">
</style>
</head>
<body ng-app="myapp">
<cust>hello</cust>
</body>
</html>
可以看到原先cust中的hello 没了,没有被保留下来,所以如果想要保留,那么就要transclude:true,并且在templace中相应的地方使用ng-transclude说明嵌入在哪.
<!DOCTYPE html>
<html>
<head>
<Meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="stylesheet" href="bootstrap.min.css">
<script src="jQuery.min.js"></script>
<script src="angular.min.js"></script>
<script src="bootstrap.min.js"></script>
<script type="text/JavaScript">
var app = angular.module('myapp',[]);
app.directive('cust',function(){
return {
restrict: 'EA',
replace: true,
transclude: true,
template:"<div>world<div ng-transclude></div></div>"
}
});
</script>
<style type="text/css">
</style>
</head>
<body ng-app="myapp">
<cust>hello</cust>
</body>
</html>
可以看到hello被嵌入进了div中,angular还自动将其包裹在span中.
当然如果你本来就有了span,angular是不会再加span的.
上面的保留了hello,hello是cust的子元素,如果我想把cust也保留嵌入模板该怎么做,你或许说把replace改为false不就保留了.这样是可以保留,但跟我要说的不一样.
如果我把body改成<label cust>hello</label>,我想保留label该怎么做,现在只能把hello嵌入模板.
所以接下来要说的就是transclude:'element',把子元素和本身都保留下来.
<!DOCTYPE html>
<html>
<head>
<Meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="stylesheet" href="bootstrap.min.css">
<script src="jquery.min.js"></script>
<script src="angular.min.js"></script>
<script src="bootstrap.min.js"></script>
<script type="text/javascript">
var app = angular.module('myapp',
transclude: 'element',
template:"<div>world<div ng-transclude></div></div>"
}
});
</script>
<style type="text/css">
</style>
</head>
<body ng-app="myapp">
<label cust>hello</label>
</body>
</html>
可以看到label保留下来了.
下面最后一个比较6,
将上面的代码中replace改为false
一切灰飞烟灭只留下了注释.
这是为什么呢,跟踪源码
if (directiveValue == 'element') {
hasElementTranscludeDirective = true;
terminalPriority = directive.priority;
$template = $compileNode;
$compileNode = templateAttrs.$$element =
jqLite(document.createComment(' ' + directiveName + ': ' +
templateAttrs[directiveName] + ' '));
compileNode = $compileNode[0];
replaceWith(jqCollection,sliceArgs($template),compileNode);
childTranscludeFn = compile($template,transcludeFn,terminalPriority,
replaceDirective && replaceDirective.name,{
// Don't pass in:
// - controllerDirectives - otherwise we'll create duplicates controllers
// - newIsolateScopeDirective or templateDirective - combining templates with
// element transclusion doesn't make sense.
//
// We need only nonTlbTranscludeDirective so that we prevent putting transclusion
// on the same element more than once.
nonTlbTranscludeDirective: nonTlbTranscludeDirective
});
} else {
$template = jqLite(jqLiteClone(compileNode)).contents();
$compileNode.empty(); // clear contents
childTranscludeFn = compile($template,transcludeFn);
}
}
if (directive.template) {
hasTemplate = true;
assertNoDuplicate('template',templateDirective,directive,$compileNode);
templateDirective = directive;
directiveValue = (isFunction(directive.template))
? directive.template($compileNode,templateAttrs)
: directive.template;
directiveValue = denormalizeTemplate(directiveValue);
if (directive.replace) {
replaceDirective = directive;
if (jqLiteIsTextNode(directiveValue)) {
$template = [];
} else {
$template = removeComments(wrapTemplate(directive.templateNamespace,trim(directiveValue)));
}
compileNode = $template[0];
if ($template.length != 1 || compileNode.nodeType !== NODE_TYPE_ELEMENT) {
throw $compileMinErr('tplrt',
"Template for directive '{0}' must have exactly one root element. {1}",
directiveName,'');
}
可以看到,两次replaceWith是关键.