angularjs指令中的replace与transclude参数

前端之家收集整理的这篇文章主要介绍了angularjs指令中的replace与transclude参数前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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属性.


transclude是保留自定义指令子元素中的内容

默认是false

<!DOCTYPE html>
<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是关键.


转自:http://blog.csdn.net/u014788227/article/details/50435865

猜你在找的Angularjs相关文章