Specify element in ng-repeat AngularJS
Consider the following example:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.4/angular.js"></script>
<script>
angular.module('app', [])
</script>
<div ng-app='app'>
<div ng-init="tags = ['i', 'b', 't']">
<div ng-repeat = 't in tags'>{{t}}</div>
</div>
</div>
This works as intended, however I would like to be able to specify an element or attribute.
<div ng-init="tags = ['i', 'b', 't']">
<{{t}} ng-repeat = 't in tags'>{{t}}</{{t}}>
It doesn't work: Demo
How can i do this? I just want to build a html structure (with my own directives) from json. Is this good or bad best practice?
source to share
To accomplish this, you can use a directive with a custom forwarding function:
.directive('bindTagName', ['$compile', function ($compile) {
return {
transclude: true,
replace: true,
link: function (scope, elem, attrs, controller, transcludeFn) {
// get tag name
var tagName = scope.$eval(attrs.bindTagName);
// create new tag
var created = angular.element(document.createElement(tagName));
// replace current element with created tag
elem.replaceWith(created);
// call transclude function
transcludeFn(
function (clone, scope) {
$compile(created.append(clone))(scope);
}
);
}
}
}])
Given the following view:
<div ng-init="tags = ['i', 'b', 't']">
<div ng-repeat = 't in tags' bind-tag-name="t">-> {{t}}</div>
</div>
It outputs the following html:
<div ng-init="tags = ['i', 'b', 't']">
<!-- ngRepeat: t in tags -->
<i><span class="ng-binding ng-scope">-> i</span></i>
<!-- end ngRepeat: t in tags -->
<b><span class="ng-binding ng-scope">-> b</span></b>
<!-- end ngRepeat: t in tags -->
<t><span class="ng-binding ng-scope">-> t</span></t>
<!-- end ngRepeat: t in tags -->
</div>
source to share
I don't know if you can manipulate HTML tags yourself with angular. However, I can think of something that would work:
<div ng-app="app" ng-controller="appController">
<div ng-init="tags = ['i', 'b', 't']">
<i ng-show="t == 'i'" ng-repeat ="t in tags">{{t}}</i>
<br/>
<b ng-show="t == 'b'" ng-repeat ="t in tags">{{t}}</b>
<br/>
<t ng-show="t == 't'" ng-repeat ="t in tags">{{t}}</t>
<br/>
</div>
</div>
I'm not sure if this will solve your problems. For every tag you would like to use, you need to write that tag and just show it or hide it depending on the input.
example in JSFiddle .
source to share
You can do something like the following:
<div ng-init="tags = ['span', 'span', 'div']">
<span ng-repeat="t in tags track by $index"
ng-bind-html="'<' + t + '>' + t + '</' + t + '>'">
</span>
</div>
but this will add a wrapping element <span>
.
EDIT: This requires adding a link to angular-sanitize.js and adding a module dependency to your application so that it will automatically deactivate unsafe HTML:
angular.module("myApp", ["ngSanitize"])
source to share