[v1.0.0-beta.11] Collection Repeat doesn't work with Directives


#1

My markup:

    <div class="list noticias">
        <a class="item item-thumbnail-left"
           collection-repeat="post in posts | limitTo: limit"
           collection-item-width="'100%'"
           collection-item-height="112"
           href="#/app/noticia/{{post.uuid}}"
           ng-style="{height: 112}">
            <div class="item-image {{post.type}}" cache-background="{{post.thumb}}">
                <i class="ion" ng-hide="post.thumb"></i>
            </div>
            <span ng-bind-html="post.title | cut:true:60:'...'" class="{{post.type}}"></span>

            <p class="info {{post.type}}">{{fromNow(post)}} @ <i>{{post.type}}</i></p>
        </a>
    </div>

My directive:

.directive('cacheBackground', function(){
    return function(scope, element, attrs){
        if (attrs.cacheBackground == "")
            return;

        var useCached = function() {
            element.css({'background-image': 'url('+attrs.cacheBackground+')'});
            ImgCache.useCachedBackground(element);
        };

        ImgCache.isCached(attrs.cacheBackground, function (path, success) {
            if (success) {
                useCached();
            } else {
                ImgCache.cacheFile(attrs.cacheBackground, function () {
                    useCached();
                });
            }
        });
    };
})

The problem is that, when using collection, the {{post.thumb}} isn’t parsed before being called. So the parameter is just empty.

Tried to code pen it, but http://codepen.io/sidfz/pen/Frfoc… it will span some 10 alerts when loading…


Collection-repeat ng-init directive bug?
#2

Try wrapping the function in a $timeout, which will cause it run in angular’s next digest cycle.

.directive('cacheBackground', function(){
    return function(scope, element, attrs){
     // Will trigger on the next scope digest, after collection repeat 
      $timeout( function(){
        if (attrs.cacheBackground == "")
            return;

        var useCached = function() {
            element.css({'background-image': 'url('+attrs.cacheBackground+')'});
            ImgCache.useCachedBackground(element);
        };

        ImgCache.isCached(attrs.cacheBackground, function (path, success) {
            if (success) {
                useCached();
            } else {
                ImgCache.cacheFile(attrs.cacheBackground, function () {
                    useCached();
                });
            }
        });
      });
    };
})


#3

Tried on codepen and still empty…


#4

Alright, tried console.log instead of alert, and all things were being called.

Not sure what not working on production level. Any chance you can make the directive in the codepen the one you need?


#5

I just tested and this is weird:

[Log] Object (console-via-logger.js, line 173)
$$element: Object[1]
$$observers: Object
$attr: Object
cacheBackground: "http://pbs.twimg.com/media/Bu9NItzIQAAsueI.jpg"
class: "item-image twitter"
__proto__: Object

[Log] 0 (console-via-logger.js, line 173)
[Log] 0 (console-via-logger.js, line 173)

the 0 are the lenght of console.log(attrs.cacheBackground). But the first part is a console.log(attrs).


#6

Hmm, that is really odd. So are you just trying to create a background image directive?


#7

Yeah, so I can cache the images


Problem with using my own directive inside collection-repeat
#8

Hmm, well I’d let collection repeat work with cache, it does that automatically.


#9

By cache I mean imgcachejs (save image locally)


#10

I’m having the same or similar issue in beta.11 - i have something like

<ion-list class="list list-inset card">
    <ion-item class="item my-item"
              collection-repeat="post in postsqueue"
              collection-item-width="'100%'"
              collection-item-height="300"
              ng-style="300"
              href="#/postdetail/{{post.id}}">
        {{post.id}} {{post.status}}
        <timelinepost post="post"></timelinepost>
    </ion-item>
</ion-list>

“timelinepost” looks something like

.directive ( 'timelinepost', ['PostConstants', function(PostConstants) {
    return {
        restrict: 'E',
        scope: {
            'masterPost': '=post'
        },
        templateUrl: 'bobs-template.html',
        link: function(scope, element, attrs) {
            var names = [];
            _.each(scope.masterPost.posts, function(childPost) {
                names.push(childPost.to.surface.name);
            });
            scope.names = names.join(", ");
      }
    };
}]);

As far as i can tell - the link function is never hit. If i change back to ng-repeat all is well.

It seems this may be related as well?

Apologies in advance if i am way off here.


#11

I do believe it’s the same issue.
The question is how to solve it… My lists are getting bigger…


#12

I was having the same issue and I had tried a lot of different methods to get it fix.
Finally I found myself a temporary solution.
First isolate scope with the attribute by using two-way binding ‘=’, after that I use scope.$watch to check the changes and perform the task. Following is the fork of the amended code.
Hope it helps.

See the Pen wfeEo by Wayne Cheah (@waynecheah) on CodePen.


#13

Adding the $scope.$watch() indeed works. Thanks for the suggestion. Will we have to do it this way or can we expect a fix in later editions?


#14

What are the implications of using $scope.$watch() with a big list (the purpose of collection-repeat)?

Will this be the final solution? Thank you.


#15

I used it and worked. I expect soon to have a better solution but indeed this one works.


#16

Should we open an issue for this on GitHub? I do think this is a major bug. Directives are what angular is about.


#17

i was seeing a similar issue, oddly enough it was working some portion of the time to resolve a directive. i tried the watch trick and had some luck. a interesting idea for sure. I’m not sure what the protocol is for issue starting, but i’d be in favor. i’m curious if it will be addressed in the next release? it feels a bit hacky to watch these items, (if it was done behind the scenes, i’d feel better)


#18

I’m having similar issue Problem with using my own directive inside collection-repeat


#19

@mhartington, did this problem ever got resolved? I am now on v.1.0.0-final and this problem is still here, directives fail when placed inside collection-repeat. Everything runs ok with ng-repeat though.


#20

From what I remember, this is a known issue and would require a refactor of collection repeat.
It is something we know about and plan on fixing.