在模板中使用动态标记名称的Angular建议方法是什么?
我有一个包含h1-h6标签的下拉列表。用户可以选择其中任何一个,并且内容将更改为由所选标头标记(存储在$ scope中)进行包装。内容绑定到模型,即{{}}内。
要保持绑定,我可以更改标记并使用$ compile。但是,这不起作用,因为它会在Angular用模型值替换{{}}之前(显然)附加。这是页面加载时的h3。
示例:
<div id="root">
<h3 id="elementToReplace">{{ modelData }}</h3>
</div>
重新编译时,我尝试使用如下字符串:
<{{ tag }} id="elementToReplace">{{ modelData }}</{{ tag }}>
有什么想法吗?
答案 0 :(得分:5)
定义名为&#39; tag&#39;的范围变量并将其绑定到您的选择列表和自定义指令。
HTML:
<select ng-model="tag" ng-init="tag='H1'">
<option ng-value="H1">H1</option>
<option ng-value="H2">H2</option>
<option ng-value="H3">H3</option>
<option ng-value="H4">H4</option>
<option ng-value="H5">H5</option>
</select>
<tag tag-name="tag">Hey There</tag>
接下来,使用双向模型绑定将标记范围模型传递到指令中:
var app = angular.module('app',[]);
app.directive('tag', function($interpolate) {
return {
restrict: 'E',
scope: {
tagName: '='
},
link: function($scope, $element, $attr) {
var content = $element.html();
$scope.$watch('tagName', function(newVal) {
$element.contents().remove();
var tag = $interpolate('<{{tagName}}>{{content}}</{{tagName}}>')
({tagName: $scope.tagName, content: content});
var e = angular.element(tag);
$element.append(e);
});
}
}
});
请注意,在custom指令中,我们使用$ interpolate服务根据在选择列表中选择的Tag生成HTML元素。 $ watch函数用于监视标记模型的更改,当它更改时,新元素将附加到DOM。
答案 1 :(得分:0)
这是我敲了一个,即使你说你不想要它;)
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="../lib/jquery.js"></script>
<script src="../lib/angular.js"></script>
<script>
var app = angular.module('app', []);
app.controller('ctrl', ['$scope', function ($scope) {
$scope.modelData = "<h1>Model Data</h1>" +
"<p id='replace'>This is the text inside the changing tags!</p>";
$scope.tags = ["h1", "h2", "h3", "h4", "p"];
$scope.selectedTag = "p";
}]);
app.directive("tagSelector", function(){
return {
resrict: 'A',
scope: {
modelData: '@',
selectedTag: '@'
},
link: function(scope, el, attrs){
scope.$watch("selectedTag", updateText);
el.prepend(scope.modelData);
function updateText(){
var tagStart = "<" + scope.selectedTag + " id='replace'>";
var tagEnd = "</" + scope.selectedTag + ">";
$("#replace").replaceWith(tagStart + $("#replace").html() + tagEnd);
}
}
}
});
</script>
</head>
<body ng-app="app">
<div ng-controller="ctrl">
<select ng-model="selectedTag" ng-options="tag for tag in tags"></select>
<div tag-selector selected-tag="{{selectedTag}}" model-data="{{modelData}}"></div>
</div>
</body>
</html>
答案 2 :(得分:0)
更多犹太洁食版。适用于ng-repeat和嵌套指令。 工作示例here。
angular.module('myApp', [])
.directive('tag', function($interpolate, $compile) {
return {
priority: 500,
restrict: 'AE',
terminal: true,
scope: {
tagName: '='
},
link: function($scope, $element) {
$scope.$on('$destroy', function(){
$scope.$destroy();
$element.empty();
});
$scope.$parent.$watch($scope.tagName, function(value) {
$compile($element.contents())($scope.$parent, function(compiled) {
$element.contents().detach();
var tagName = value || 'div';
var root = angular.element(
$element[0].outerHTML
.replace(/^<\w+/, '<' + tagName)
.replace(/\w+>$/, tagName + '>'));
root.append(compiled);
$element.replaceWith(root);
$element = root;
});
});
}
}
})
.controller('MyCtrl', function($scope) {
$scope.items = [{
name: 'One',
tagName: 'a'
}, {
name: 'Two',
tagName: 'span'
}, {
name: 'Three',
}, {
name: 'Four',
}];
});
用途:
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<tag class="item" tag-name="'item.tagName'" ng-repeat="item in items">
{{item.name}}
</tag>
</div>
</div>