javascript 带有 angularjs 指令的动态标签
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19987722/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dynamic tag with angularjs directive
提问by Alex
I would like to create an element directive in angularjs that produces an html element from a json blob passed as an attribute. I have tried quite a few variations of the following...
我想在 angularjs 中创建一个元素指令,它从作为属性传递的 json blob 生成一个 html 元素。我已经尝试了以下相当多的变体......
demoApp.directive("element", function() {
return {
restrict: "E",
scope: {
attributes: "@",
name: "@"
},
template:
function(name, attributes) {
var templateString = "<" + attributes.tag;
for (attribute in attributes) {
if (attribute != "name_displayed" && attribute != "tag") {
templateString += " " + attribute + "=\"" attributes[attribute] + "\"";
}
}
templateString += " name=\"" field + "\"";
templateString += ">";
templateString += "</" + attributes.tag + ">";
return attributes.name_displayed + ": " + templateString;
}(name, attributes)
};
});
The html looks like
html看起来像
<div ng-repeat="(name, attributes) in fields">
<element name="{[{name}]}" attributes="{[{attributes}]}"></element>
</div>
Where an attributes json object looks like
属性 json 对象的样子
{"name_displayed":"Agency","size":"30","tag":"input","type":"text"}
And a name looks like
一个名字看起来像
agency
It looks like I cannot use a function for a template, and it also looks like I cannot get access to the attributes or name objects.
看起来我无法将函数用于模板,而且我似乎无法访问属性或名称对象。
采纳答案by Adam
Check this out: http://jsfiddle.net/es4Y6/1/
看看这个:http: //jsfiddle.net/es4Y6/1/
var app = angular.module('hmm', []);
function ctrl($scope) {
$scope.fields = {
first: '{"name_displayed": "Agency", "size": "30", "tag": "input", "type": "text"}',
second: '{"name_displayed": "Foo", "size": "30", "tag": "input", "type": "password"}',
third: '{"name_displayed": "Bar", "size": "30", "tag": "input", "type": "number"}'
};
}
app.directive('blah', function() {
var template = function(name, attributes) {
var templateString = "<" + attributes.tag;
for (var attribute in attributes) {
if (attribute != "name_displayed" && attribute != "tag") {
templateString += " " + attribute + '="' + attributes[attribute] + '"';
}
}
templateString += ' name="' + name + '"';
templateString += ">";
templateString += "</" + attributes.tag + ">";
return attributes.name_displayed + ": " + templateString;
};
return {
restrict: "E",
link: function(scope, element, attrs){
var attributes = angular.fromJson(attrs.attributes);
var tpl = template(attrs.name, attributes);
element.html(tpl);
}
};
});
I assume that by "json blob" you mean json string. If not, then you mean just JS object. In such case, update $scope.fields
and remove angular.fromJson()
.
我假设“json blob”是指 json 字符串。如果没有,那么您的意思只是 JS 对象。在这种情况下,更新$scope.fields
和删除angular.fromJson()
。
<div ng-app="hmm">
<div ng-controller="ctrl">
<div ng-repeat="(name, attributes) in fields">
<blah name="{{name}}" attributes="{{attributes}}"></blah>
</div>
</div>
</div>
It works, however it's a very bad approach to the problem you are trying to solve.
它有效,但是对于您要解决的问题来说,这是一种非常糟糕的方法。
回答by Vadim
You can implement your logic in link
function instead of a template
. Try this:
您可以在link
函数而不是template
. 试试这个:
HTML
HTML
<element ng-repeat="field in fields" />
JavaScript
JavaScript
angular.module('demo', []).
controller('demoCtrl', ['$scope', function($scope) {
$scope.fields = [{
"tag": "input",
"type": "text",
"value": "Demo app",
"name": "my_input",
"label": "My Text"
}, {
"tag": "input",
"type": "checkbox",
"checked": "checked",
"name": "my_checkbox",
"label": "My Checkbox"
}, {
"tag": "input",
"type": "button",
"value": "Click Me",
"name": "my_button"
}];
}]).
directive('element', function() {
return {
restrict: "E",
replace: true,
template: "<div></div>",
link: function(scope, element, attrs) {
var label,
el,
key,
field;
field = scope.field;
if('label' in field) {
label = document.createElement('label');
label.innerHTML = field.label;
element.append(label);
element.append(document.createTextNode(': '));
}
el = document.createElement(field.tag);
for(key in field) {
if(field.hasOwnProperty(key) && // avoid prototype properties
key !== 'tag' && // avoid tag
key !== 'label' && // avoid label
key[0] !== '$' // avoid angular staff derived from scope
) {
el.setAttribute(key, field[key]);
}
}
element.append(el);
}
};
});
Here is a working example: http://plnkr.co/edit/B1RigXrzA2l1kIVNVXGw?p=preview
这是一个工作示例:http: //plnkr.co/edit/B1RigXrzA2l1kIVNVXGw?p=preview