Search code examples
angularjsangularjs-directiveangularjs-ng-repeatangularjs-factory

How does the expression in ng-repeat work?


I'm trying to figure out how to loop through an array of objects, with ng-repeat.

I've got a factory set up like this, with three sets data in it:

mainApp.factory("dashboardContent", function() {
    return {
        contentBoxes: [
            {
                boxType: "image",
                boxIcon: "icons-image",
                boxTitle: "on Chapter 1, paragraph 3",
                header: {
                    title: "Lorem ipsum title sit amet",
                    subtitle: "by Lorem Ipsum"
                },
                authorImage: "/asssets/ssfsgterwes",
                embedContent: ""
            },
            {
                boxType: "audio",
                boxIcon: "icons-audio",
                boxTitle: "on Chapter 12, paragraph 2",
                header: {
                    title: "lorem ipsum audio sit maet",
                    subtitle: "by multiple objects"
                },
                authorImage: "/asssets/ssfsgterwes",
                embedContent: ""
            },
            {
                boxType: "quote",
                boxIcon: "icons-lightbulb",
                boxTitle: "on Chapter 01, paragraph 5",
                header: {
                    title: "lorem ipsum quote sit maet",
                    subtitle: "by multiple objects parsing"
                },
                authorImage: "/asssets/ssfsgterwes",
                embedContent: ""
            }
        ]
    }
})

And a directive where I've injected the factory:

.directive('contentBox', function(dashboardContent) {
    return {
        restrict: 'E',
        scope: {},
        replace: true,
        templateUrl: '/modules/contentbox.html',
        link: function (scope, element) {
            scope.contentData = dashboardContent.contentBoxes;
            if (!$.isEmptyObject(scope.contentData.header)) {
                element.children('.content').prepend(
                    '<div class="content-header">' +
                        '<span class="content-title">' +
                            scope.contentData.header.title +
                        '</span>' +
                    '   <br/>' +
                    '</div>'
                );
                if (!$.isEmptyObject(scope.contentData.header.subtitle)) {
                    element.find('.content-header').append(
                        '<span class="content-author">' +
                            scope.contentData.header.subtitle +
                        '</span>'
                    );
                }
            }
        }
    }
})

In my view, I'm trying to loop through it like this:

<content-box ng-repeat="content in contentData"></content-box>

What's the expression I'd need to use in this case? I can't understand from the ng-repeat docs how this expression works, I've figured out that in "content in contentData", contentData is referring to my set of of objects, but what is the first word (content, as I set it here), what does it refer to?

Also, did I set up this scope correctly? Like in the code above:

scope.contentData = dashboardContent.contentBoxes;

The output that I'm getting from this are three empty content boxes, so I'm guessing it's looping through it, but no data is being printed in them - i.e. {{contentData.boxTitle}} just returns empty

Am I using ng-repeat correctly in this situation ?


Solution

  • You are injecting your service dashboardContent directly into your directive. It's not necessary. Insted you could inject it into your controller, access single array elements with ng-repeat and pass those to your directive.

    mainApp.controller('ContentCtrl', function($scope, dashboardContent) { 
      $scope.contentData = dashboardContent.contentBoxes;
    });
    

    In your directive code replace

    scope: {}
    

    with

    scope: { contentData: '='}
    

    and remove line scope.contentData=...

    This way you'll have a directive with isolate scope and you can pass a value to this scope in your html like this:

    <div ng-controller="ContentCtrl" ng-repeat="content in contentBoxes">
      <content-box contentData="content"></content-box>
    </div>