LaserBeak
LaserBeak

Reputation: 3285

ng-repeat and render different HTML as per conditional statement

So in angular we can do

<tag ng-repeat="item in items">content..</tag> 

or

<tag ng-repeat-start="item in items"></tag><tag ng-repeat-end></tag>

I was wondering if there's a way to conditionally create the HTML, depending on the value of property on a javascript object. I know server side templating engines let mix code and HTML, so I was wondering if there's some way I could achieve something like the following.

contents of someview.html

<div ng-controller="someController as ctrl">

{{foreach(ctrl.items)

{{
    if (item.type == 'textbox')
    '<input type="text" value="item.value" />'
}}

{{
    if (item.type == 'checkbox')
    '<input type="checkbox" checked="item.value" />'
}}

end-foreach}}

</div>

I thought I would just use ng-if statement, but it doesn't cut it, since I don't want it to redundantly iterate over every object for each different element type and I also have a certain order I wish to preserve between the generated html elements, not simply generate all textbox elements first and then all checkbox etc. elements.

so

<input type="textbox" ng-if="item.type == 'textbox'" ng-repeat="item in items"/>

<input type="checkbox" ng-if="item.type == 'checkbox'" ng-repeat="item in items"/>

Won't cut it.

I am thinking I am going to have to use a directive and decorate an element with an attribute. Can the directive overwrite the element it's declared on with custom HTML ?

Upvotes: 1

Views: 1582

Answers (3)

kurian
kurian

Reputation: 1

you can try using the "?" operator. something like this

<div ng-repeat="item in vm.items">
   <input type="(item.type == 'textbox') ? item.type : checkbox" checked="item.value" />
</div>

Upvotes: 0

illeb
illeb

Reputation: 2947

Try using ng-include conditionally, a very clean way by my opinion:

<tag ng-repeat="item in item"><div ng-include="getTemplate(item)"></div></tag> 

and in your controller:

$scope.getTemplate = function(item){
   if(item.type == 'textbox')
     return 'textboxTemplate.html';

   if(item.type == 'checkbox')
     return 'checkboxTemplate.html';

   //and so on...
}

Then, declare your scripts, either via the <script> tag or via the $templateCache service:

<script type="text/ng-template" id="checkboxTemplate.html">
  <input type="checkbox" ng-model="item.value"/>
</script>

Upvotes: 0

JayChase
JayChase

Reputation: 11525

You can use the ng-repeat directive as an element. That way you could have the tags with the ngIf conditions as its content.

    <ng-repeat ng-repeat="item in vm.items">
        <tag ng-if="item.type == 'textbox'">   
            <input type="textbox">
        </tag>
        <tag ng-if="item.type == 'checkbox'">
            <input type="checkbox"/>
        </tag>            
    </ng-repeat>

Upvotes: 2

Related Questions