AngularJS / Isotope— calling .isotope(“reLayout”) after page loads

旧巷老猫 提交于 2019-12-13 19:18:27

问题


I'm trying to use isotope with AngularJS (to layout a set of "cards"). Instead of adding to the DOM directly, I add elements via isotope using container.isotope('insert',element).

I do all this in the linking function, but it appears that when I insert stuff into the DOM in the linking function, the sizes aren't set correctly (in my case, height is 0), so the elements don't get drawn properly.

If I resize the window, the elements then get draw correctly. I was thinking that I could use a watch on $viewContentLoaded to call the function that refreshes the layout of isotope (i.e., container.isotope('reLayout')), but the $viewContentLoaded event never seems to fire. Am I doing something wrong or is there some other methodology I should be using?

EDIT: I got the function to run by doing scope.$root.$on('$viewContentLoaded',function(){}); but that did not help...(it appears to get called to early)

EDIT 2: After playing around a lot more, the div's are getting added properly with isotope, but because it's parent div has 0 height, the children sizes are getting set properly. If I do setTimeout(element.isotope('relayout'),100) it works fine. Any way to mimic this?

module.directive('tileGrid',function(){
var mytemplate = '<div class="item {{card.class}}">{{card.Title}}</div>';
var original = angular.element(mytemplate);

return {
    restrict: 'A',
    replace: true,
    transclude: true,
    template: '<div id="tileGridContainer"></div>',     
    link: function(scope,element,attrs)
        { 
            element.isotope({itemSelector:'.item',layoutMode:'fitRows'});                               
            var curCards = scope.cards.map(function(a){ return a.nextView;});                                               

            scope.$watch('scope.cards',function()
            {       
//will do this for diff, but for now iterate over all elements
                for(var i=0;i<scope.cards.length;i++)
                {                           
                    var card = scope.cards[i];

                    var childScope = scope.$new();
                    childScope.card = card;


                    scope.compile(original)(childScope,function(clonedElement,childScope){                          
                        element.isotope('insert',clonedElement);                            
                    });


                    scope.$on('$viewContentLoaded', function(){ console.log("view loaded"); });

                }
            }

            );              
        }
    };
});

回答1:


I'm not entirely sure if this is the issue or not. I've run into an issue where linking got all messed up because I was modifying the DOM in the postLink. I ended up moving all DOM manipulation to be deferred using setTimeout.

However... now that I go back and try to reproduce the issue, I'm no longer seeing it.

Angular UI mentions the problem, and it was actually having this come to my knowledge that helped me fix the problem I was experiencing:

Angular-UI modules/directives/select2/select.js:103 on GitHub

You might try to do all DOM manipulation in the compile function, or in a setTimeout call.

If you haven't already, read AngularJS: Directives about when it is safe to do DOM manipulation, and when not.



来源:https://stackoverflow.com/questions/11980121/angularjs-isotope-calling-isotoperelayout-after-page-loads

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!