nativescript-ngx-slides icon indicating copy to clipboard operation
nativescript-ngx-slides copied to clipboard

dynamic slides not working

Open developper89 opened this issue 8 years ago • 24 comments

hello, i am trying to use this plugin inside *ngFor <slides pageIndicators="false" loop="false"> <slide *ngFor="let item of items; let i = index"> <GridLayout><Label [text]="i"></Label> </slide> </slides> the plugin crashes and i am unable to slide between the slides

developper89 avatar Apr 28 '17 18:04 developper89

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.

sarpt avatar Apr 29 '17 10:04 sarpt

@sarpt so what is the ideal solution?

Jonatthu avatar May 18 '17 21:05 Jonatthu

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;"> <ScrollView > <StackLayout *ngFor="let comp of items[i]">

ChrAraya avatar Aug 31 '17 17:08 ChrAraya

@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.

JoshDSommer avatar Aug 31 '17 17:08 JoshDSommer

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

ChrAraya avatar Aug 31 '17 18:08 ChrAraya

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.

JoshDSommer avatar Aug 31 '17 19:08 JoshDSommer

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

ChrAraya avatar Aug 31 '17 19:08 ChrAraya

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

JoshDSommer avatar Sep 01 '17 00:09 JoshDSommer

+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!

sfaessler avatar Sep 13 '17 19:09 sfaessler

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).

sittingbool avatar Sep 24 '17 14:09 sittingbool

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.

heese avatar Oct 12 '17 21:10 heese

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

JoshDSommer avatar Oct 12 '17 21:10 JoshDSommer

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.

heese avatar Oct 12 '17 22:10 heese

That sounds perfect. Thank you @heese

JoshDSommer avatar Oct 12 '17 22:10 JoshDSommer

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.

heese avatar Oct 13 '17 05:10 heese

@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).

gabitoesmiapodo avatar Oct 14 '17 00:10 gabitoesmiapodo

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);
		}
	}
}

heese avatar Oct 15 '17 20:10 heese

Thank you!

gabitoesmiapodo avatar Oct 17 '17 12:10 gabitoesmiapodo

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

JoshDSommer avatar Oct 18 '17 01:10 JoshDSommer

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?

nikunjgajera avatar Nov 24 '17 15:11 nikunjgajera

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.)

heese avatar Nov 24 '17 19:11 heese

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

JoshDSommer avatar Nov 25 '17 03:11 JoshDSommer

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

Arham-Aalam avatar Sep 28 '18 21:09 Arham-Aalam

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

heese avatar Sep 28 '18 23:09 heese