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,'');
}

copeDirective) {
markDirectivesAsIsolate(templateDirectives);
}
directives = directives.concat(templateDirectives).concat(unprocessedDirectives);
mergeTemplateAttributes(templateAttrs,newTemplateAttrs);

ii = directives.length;
} else {
$compileNode.html(directiveValue);
}
}

可以看到,两次replaceWith是关键.


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

相关文章

ANGULAR.JS:NG-SELECTANDNG-OPTIONSPS:其实看英文文档比看中...
AngularJS中使用Chart.js制折线图与饼图实例  Chart.js 是...
IE浏览器兼容性后续前言 继续尝试解决IE浏览器兼容性问题,...
Angular实现下拉菜单多选写这篇文章时,引用文章地址如下:h...
在AngularJS应用中集成科大讯飞语音输入功能前言 根据项目...
Angular数据更新不及时问题探讨前言 在修复控制角标正确变...