JoshDSommer / nativescript-ngx-slides

A NativeScript + Angular module for to add a slides component to your mobile app
Other
45 stars 34 forks source link

dynamic slides not working #15

Open developper89 opened 7 years ago

developper89 commented 7 years ago

hello, i am trying to use this plugin inside ngFor ` <slide ngFor="let item of items; let i = index">

` the plugin crashes and i am unable to slide between the slides
sarpt commented 7 years ago

That's because the slides are created before the ngFor populates the dom. The slides aren't recreated after that though. I did somewhat hacky fix for that: slides are created first, then further recreation of slides is being done after 'changes' observable fires on ContentChildren. It's not ideal - changes to iterable ngFor is using will be reflected in the slides, but the slides may not be in correct order before first sliding action, resulting in slides jumping or not showing properly during the first slide after change. The other thing, because AFAIK "changes" observable isn't replaying content already emitted, slides have to be created once before subscribing to ContentChildren. If you want to try there's a "ngfor" branch on my fork, however keep in mind its not ideal solution.

Jonatthu commented 7 years ago

@sarpt so what is the ideal solution?

ChrAraya commented 7 years ago

i have the same problem, i get some info with a service from a DB to create dynamic slides but this happend. all the slides are on top of another. captura de pantalla 2017-08-31 a la s 14 45 38

this is part of my code

<slides id="slides" (changed)="slideChanged()" #slides >

            <slide class="slide" *ngFor="let number of items; let i = index;">
                <!-- Controla el Scroll de la Slide  -->
                <ScrollView  >
                    <!-- Para contener las cartas  -->
                    <StackLayout *ngFor="let comp of items[i]">
JoshDSommer commented 7 years ago

@ChAraya I think the code called in the ngAfterViewInit (https://github.com/TheOriginalJosh/nativescript-ngx-slides/blob/master/slides/app/slides/slides.component.ts#L96) needs to be abstracted out into a public function you can then call after your dynamic data has loaded. This might be all you need to fix it. It's not a use cased i've had myself(yet) but I understand the need.

ChrAraya commented 7 years ago

yea, a saw you solution to make a manualInit and i called but nothing happend

i need do something else ?

captura de pantalla 2017-08-31 a la s 15 48 30

JoshDSommer commented 7 years ago

Hmm, I'm not sure really. could you open a Pull Request with your ManualInit in it? it would probably be a nice addition once the kinks are worked out.

ChrAraya commented 7 years ago

ok, i will do it later, a question.

its there a way that i can know when the slides gonna be slide to other page ? before the change event occured?

'cause with that i can implement a parcial solution to my problem and make the slides "dynamic" but really not dynamic just know when no to slide to the next slide

JoshDSommer commented 7 years ago

I'm not sure I follow.

There are changed and finished events you can watch for https://github.com/TheOriginalJosh/nativescript-ngx-slides/blob/master/slides/app/slides/slides.component.ts#L62

sfaessler commented 6 years ago

+1 - is there a solution available in the meanwhile? I'm having the same problem. I have a first slide which comes from the view directly and further slides which comes dynamically from a json file which is loaded in the .ts

See code here: https://pastebin.com/G9EQXKMP

simulator screen shot 13 09 2017 21 34 56

Looking forward for any help with this.

Thanks!

sittingbool commented 6 years ago

I fixed this by placing a ngIf into the slides tag that is checking weather the array is empty and only shows after data is laded into the array. Obviousely there is ap problem with changing the content of the array that is used in the ngfor. If there are changes maybe it also would help to make the array empty first and then set the refreshed data. then angular would rereder the slides-element (hopefully).

heese commented 6 years ago

I have forked the project and changed the file slides.component.ts to init the slides only when there some (using ngAfterViewChecked). This way I can load the data asynchronously and use *ngFor to create the slide elements.

It is more a hack than a solution (and I don't have time to test it properly) but it works in my situation quite well -- maybe, you have a similar one. Here is the git repository: https://github.com/heese/nativescript-ngx-slides

@TheOriginalJosh Can this be an approach to solve the dynamic loading of slides? I create a pull request if you want to.

JoshDSommer commented 6 years ago

@heese that sounds great! good work man, thank you!

heese commented 6 years ago

I like your plugin and I am happy to contribute.

Since I needed it I have also introduced a new attribute autoInit in my code (by default true) which allows me -- if set to false -- to manually trigger the initialisation.

JoshDSommer commented 6 years ago

That sounds perfect. Thank you @heese

heese commented 6 years ago

Turned my hack into a solution (still no time to test it properly). You can subscribe to changes of QueryList and, thus, re-init the slides whenever they change. It is as simple as

this.slides.changes.subscribe(() => {
     this._init();
});

Note: The dynamic data has to be loaded in ngAfterViewInit or later.

gabitoesmiapodo commented 6 years ago

@heese Sorry to bother you, but could you provide an example of how are you using your fork?

I just need something to get me going, I could use your version, but the slides got badly initialized (not the right size).

heese commented 6 years ago

Hi @gabitoesmiapodo

please find below an example which is derived from the code I am working on at the moment. In my case I needed the slides to have a certain width (depending on the display) and height (fixed). I have removed all unimportant bits and pieces and hope I haven't deleted anything essential -- meaning I have not tested the code below. Let me know if you need also the unmentioned import statements.

Furthermore, I copied the slides module into my project because Josh will hopefully update his code at some point (making my fork superfluous) and make it available on npm.

The method listLatestRedemptions does the async call to an endpoint for retrieving the data, e.g., something like return this.http.(url, options).

I found it helpful having the slides change automatically because you can then easily see if the slides are initialised properly and not rendered one over the other.

I hope it helps.

component.html:

<slides #slideShow [loop]="true" [pageHeight]="240" [pageWidth]="slideWidth">
    <slide *ngFor="let item of redemptions">
        <Label [text]="item.name + ' from ' + item.address"></Label>
    </slide>
</slides>

component.ts:

import * as platform from "platform";

export class RedemptionComponent implements OnInit, AfterViewInit {
    isLoading: boolean;

    redemptions: LatestRedemption[] = [];

    slideWidth: number;

    @ViewChild('slideShow') slideView: SlidesComponent;

    slideViewTimerId: number;

    ngOnInit() {
        super.ngOnInit();
        // display width - 2 * padding 'inner-container'
        this.slideWidth = Math.ceil(platform.screen.mainScreen.widthDIPs - 12);
    }

    ngAfterViewInit() {
        this.loadLatestRedemptions();
    }

    loadLatestRedemptions() {
        if (this.isLoading) {
            return;
        }

        this.isLoading = true;
        this.transactionService.listLatestRedemptions().subscribe(data => {
                this.redemptions = data;
                this.isLoading = false;
                this.startAutoNextSlide();
            }
        );
    }

    startAutoNextSlide() {
        if (!isNullOrUndefined(this.slideView)) {
            this.slideViewTimerId = timer.setInterval(() => {
                    this.slideView.nextSlide(1000);
                },
                4000);
        }
    }
}
gabitoesmiapodo commented 6 years ago

Thank you!

JoshDSommer commented 6 years ago

@heese please open a PR and I will merge it in. Thank you.

nikunjgajera commented 6 years ago

I have same issues, please see below code

slides.html

<slides pageIndicators="true" id="slides" #slides>
    <slide class="slide-1" *ngFor="let player of players">
        <Label [text]="player.name"></Label>
    </slide>
</slides>

slides.component.ts

export class SlidesComponent implements OnInit {
    players : Array<Player> = [];
    @ViewChild("slides") slides: ElementRef;
    ngOnInit() {
        this.handlePlayer();
    }
    handlePlayer() {
        //Call api and get data
        this.players = data;
    }    
}

when i execute tns run android i got below response(overlap all player name) selection_003

how can i resolve it?

heese commented 6 years ago

At a quick glance you are setting this.players too early. Try setting it in ngAfterViewInit. It might be that you need to use the code of the fork I created. (Haven't managed to create the PR yet.)

JoshDSommer commented 6 years ago

@nikunjgajera I just published @heese PR in version 0.4.5 https://github.com/TheOriginalJosh/nativescript-ngx-slides/pull/43

Arham-Aalam commented 5 years ago

I'm not sure I follow.

There are changed and finished events you can watch for https://github.com/TheOriginalJosh/nativescript-ngx-slides/blob/master/slides/app/slides/slides.component.ts#L62

link is not valid now. can you share again

heese commented 5 years ago

This was probably pointing to here: https://github.com/TheOriginalJosh/nativescript-ngx-slides/blob/master/lib/src/slides/slides.component.ts#L62