3

Say one have a list of multiple type of data defined in a controller as follows:

$scope.list = [
    {text: "Remember BASIC?"},
    {code: "10   a = a+1"},
    // many additional lines…
];

Which we want to interpolate in the view depending on each individual type as follows:

<p>Remember BASIC?</p>
<code>10   a = a+1</code>

How would you do that?

[edit] Clarification about what to obtain

List is a descriptionof an arbitrary number of "paragraph" of arbitrary types. Here is an more extensive list:

$scope.list = [
    {text: "Remember BASIC?"},
    {code: "10   a = a+1"},
    {text: "Bla bla"},
    {text: "Bla bla"},
    {text: "Bla bla"},
    {text: "Bla bla"},
    {text: "Bla bla"},
    {text: "Bla bla"},
    {code: "20   b = a+1"},
    {code: "30   c = b+1"},
    {text: "Bla bla"},
    // many additional lines…
];

And the expected result:

<p>Remember BASIC?</p>
<code>10   a = a+1</code>
<p>Bla bla</p>
<p>Bla bla</p>
<p>Bla bla</p>
<p>Bla bla</p>
<p>Bla bla</p>
<p>Bla bla</p>
<code>20   b = a+1</code>
<code>30   c = b+1</code>

etc.

It's not an issue to have an englobing tag, but I don't want an englobing tag for every single "paragraph".

4 Answers 4

6

I'm not 100% sure what do you mean by

// many additional lines…

but if your list looks like

$scope.list = [   

       {text: "Remember BASIC?"},
       {code: "10   a = a+1"},
       {text: "Remember Loundy?"},
       {code: "10   a = a+3"}  
   ....
  ];

you can use ng-repeat-start /end

please see here http://jsbin.com/zawige/3/edit

  <p ng-repeat-start="i in list" ng-if="i.text">{{i.text}}</p>
  <code ng-repeat-end ng-if="i.code">{{i.code}}</code>
Sign up to request clarification or add additional context in comments.

2 Comments

You can toss an ngIf those to clear up the empty tags being generated.
@StéphanedeLuca please see here jsbin.com/zawige/3/edit is working thanks to TheSharpieOne suggestion
2

Yes you can do this with a directive that loads a dynamic template:

var myApp = angular.module('myApp',[]);

function getTemplate(type) {
    if(type === 'text') {
        return '<p>{{item.contents}}</p>';
    }
    else if(type === 'code') {
        return '<pre>{{item.contents}}</pre>';
    }

    return '{{item.contents}}';
}

myApp.directive("customListItem", function($compile) {
    return {
        restrict: 'E',
        scope: {
            item: '='
        },
        link: function($scope, $element) {
            $element.html(getTemplate($scope.item.type));
            $compile($element.contents())($scope);
        }
    };
});


function MyCtrl($scope) {
    $scope.list = [
        {type: 'text', contents: "Remember BASIC?"},
        {type: 'code', contents: "10   a = a+1"}
    ];
}

You could probably write that ng-repeat so that you can use your original list structure. The key here is $element.html that injects the correct template into the original and $compile that interprets the bindings in it. Note that the original custom-list-item element will still be present in the DOM. No way you can eliminate that with ng-repeat.

Here it is in action.

Comments

1

I would change the structure like so:

{
    content: "Remember BASIC?",
    type: "text",
}

Then you could do

<div ng-repeat="item in list">
  <div ng-switch="item.type">
    <div ng-switch-when="text"><p>{{item.content}}</p></div>
    <div ng-switch-when="code"><code>{{item.content}}</code></div>

If you must/want to stick with the structure as it is now, you could nest ng-repeat:

<div ng-repeat="item in list">
  <div ng-repeat="(type, text) in item">
     <div ng-switch="type"> ...

Comments

0

Change your object model:

$scope.list = [
{
    text: "Remember BASIC?",
    code: "10   a = a+1"},
    // many additional lines…
},
{
    text: "Remember Test?",
    code: "10   a = a+4"},
    // many additional lines…
}];

Then in your template:

<div ng-repeat="item in list">
  <p>{{item.text}}</p>
  <code>{{item.code}}</code>
</div>

2 Comments

This creates extraneous div for each element, which is not compliant to the specs @Taras Kostiuk
hm... then you need to write custom directive and add needed DOM elements in directive link function

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.