benjamincharity / angular-flickity

👆 An AngularJS wrapper for Flickity (Touch, responsive, flickable carousels)
Other
33 stars 23 forks source link

Ng-repeated images appearing BEFORE flickity viewport. #91

Open dbarrett24 opened 7 years ago

dbarrett24 commented 7 years ago

I beleive I'm having a similar issue to the person in this StackOverflow link:

https://stackoverflow.com/questions/35107652/flickity-carousel-items-pushed-out-of-viewport-with-ng-repeat

I haven't found a solution.

I'm using a custom directive modal with a flickity carousel that will show videos/images.

Here is my site thus far: dave-barrett.com

$scope.flickityOptions={ cellSelector: '.carousel-media-cell', cellAlign: 'left', pageDots: true, // groupCells: 3, adaptiveHeight: true, imagesLoaded: true, autoPlay: true, contain: true }

The array in the JSON looks like: "files": [ "./images/videos/dayz-light-leaks.mp4", "./images/screenshots/Basketbrawl.png", "./images/screenshots/Basketbrawl-1.png", "./images/screenshots/Basketbrawl-2.png", "./images/screenshots/Basketbrawl3.png"
]

I get the images to load, but they appear outside of the flickity viewport.

benjamincharity commented 7 years ago

Hey @dbarrett24 is it possible that you fixed your issue? It seems that the items are nested correctly:

screen shot 2017-09-05 at 8 24 06 am

Are you still seeing a different result?

dbarrett24 commented 7 years ago

Thanks for the response! Yeah, so I'm still having the problem. I apologize i realized I didn't specify where it's occurring. So I actually have 2 carousels. The one in your screen shot are the project cards. Those are working correctly as I actually just hard-coded them and didn't use ng-repeat.

The carousel that is giving me trouble is found after you click on one of those cards and a modal shows up with the project's information. With this carousel, I'm trying to make a slideshow of screenshots/video. The images I'm just pulling from a JSON file with the array of images for that project, but for whatever reason, the images are showing outside the flickity viewport in the modal. Every time I look at the code I feel like I'm doing this correctly, but I can't figure out what's happening :/

Here are screenshots of what I'm seeing:

Images appear one on top of the other: [image: Inline image 1]

It appears as though the NG-repeat ends and restarts for each image, each image appears outside of the flickity viewport. [image: Inline image 2]

On Tue, Sep 5, 2017 at 6:25 AM, Benjamin Charity notifications@github.com wrote:

Hey @dbarrett24 https://github.com/dbarrett24 is it possible that you fixed your issue? It seems that the items are nested correctly:

[image: screen shot 2017-09-05 at 8 24 06 am] https://user-images.githubusercontent.com/270193/30061024-b31f4e5a-9213-11e7-8f78-e7087dfc3f87.png

Are you still seeing a different result?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/benjamincharity/angular-flickity/issues/91#issuecomment-327159719, or mute the thread https://github.com/notifications/unsubscribe-auth/AXIqRwrWgha7RJ3pbOJ4DflJNpqJ5vcIks5sfT20gaJpZM4PMRkr .

-- David Barrett

benjamincharity commented 7 years ago

Ahh I didn't go quite deep enough. I see the issue now.

I was trying to compare against my existing demo for remote data but Codepen seems to be enforcing https for all requests :/ I'll have to work on that later.

That being said.. it seems like a very possible reason is that Flickity is being instantiated before the ng-repeat is fully populated. I would try manually creating the Flickity slider using the service as I do in the demo linked above. Wrap the creation inside a setTimeout to make sure it happens after the ng-repeat.

Not ideal, but as I've pointed out in other issues, the underlying Flickity library wasn't really created for a model driven approach so hacks are what we are left with.

(I'll try to fix the demo this evening)

Let me know how it goes.

dbarrett24 commented 7 years ago

Sorry for the trouble. I'm relatively new to development.

Could you guide me on using the setTimeout/$timeout in this situation, I was having some trouble interpreting your demo and translating it to use in my code.

Here is the code I'm working with:

<div  class="carousel-wrapper" id="team-slider" bc-flickity="{{flickityOptions}}">
      <div class="card" ng-repeat="teamData in teamData">
        <img ng-src="{{teamData.logo}}">
      </div>
</div>

Using a controller and service. Here is the portion of the Controller i think i'd need to work with: This is my attempt: I'm not quite sure what I'm doing wrong.

mainService.getTeams().then(function (teamData) {

        $scope.teamData = teamData;
        console.log($scope.teamData)

        var element = angular.element(document.getElementById('team-slider'));

        $timeout(function () {

            // Initialize our Flickity instance
            FlickityService.create(element[0], element[0].id);
        });
    });

I feel like I'm close, but I'm getting an Error from Flickity saying: "This ID is already in use", referring to the ID "team-slider"

The repo to the project I'm currently working on is: https://github.com/dbarrett24/basketbrawwl-app

The files I've been working in:

./public/views/team-choicesCtrl.js ./public/views/team-choices.html


**Edit, I was able to get the desired visual (working carousel), but still receive the error: "This ID is already in use". Not sure why it's showing up. Thanks!

***EDIT AGAIN: Tried hosting the code I had temporarily, but noticed the carousel was broken again, the ng-repeated cells are showing up outside of the flickity viewport:

Here is the hosted version, Most source code available in the inspector: http://basketbrawwl.dave-barrett.com/#!/team-select

benjamincharity commented 7 years ago

With the code above, you are actually instantiating the flickity directive twice. The data attribute in the dom (bc-flickity) is trying to initialize a flickity slider using the ID of the element that it is on. Then the controller is trying to manually create another slider using that same ID which throws the error you are seeing.

I believe if you remove the bc-flickity attribute, it should work. You are still seeing the broken version because the $timeout is specifically making the service wait until after the DOM has finished, so the directive version of the slider wins.

You can pass your flickity options object to the service at creation: FlickityService.create(element[0], element[0].id, flickityOptions);