Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Demo: Angular 2 + TypeScript #37

Closed
leocaseiro opened this issue Jun 9, 2016 · 25 comments
Closed

Demo: Angular 2 + TypeScript #37

leocaseiro opened this issue Jun 9, 2016 · 25 comments

Comments

@leocaseiro
Copy link
Contributor

leocaseiro commented Jun 9, 2016

Update: Check the solution here

Hi @TheOriginalJosh,

Thanks for this amazing plugin.

I'm trying to setup with Angular, following your instructions, but I'm very confused. It's not really clear what steps I need to follow.

Could you please help me to build an example? That's what I have so far. Thanks:

import {Component, OnInit} from '@angular/core';
import {registerElement, ViewClass} from "nativescript-angular/element-registry";

var SlideContainer = require("nativescript-slides").SlideContainer;
SlideContainer.angular = true; // set the SlideContainer's property of angular to true
registerElement("SlideContainer", () => SlideContainer);

@Component({
    selector: 'slidedemo',
    template: `
    <SlideContainer>
        <Slide class="slide-1" *ngFor="let img of images">
            <Label [text]="img.title"></Label>
            <Image [src]="img.source"></Image>
        </Slide>
    </SlideContainer>
    `
})
export class SlideDemoComponent implements OnInit {

    public images: Array<any> = [];

    ngOnInit() {
        this.images.push(
            {
                title: 'Sports',
                source: 'http://lorempixel.com/400/200/sports/1/'
            }
        );
        this.images.push(
            {
                title: 'Cats',
                source: 'http://lorempixel.com/400/200/cats/1/'
            }
        );
        this.images.push(
            {
                title: 'Food',
                source: 'http://lorempixel.com/400/200/food/1/'
            }
        );
    }


  /** 
   * Then in your angular component in the ngAfterViewInit.
   * you will want to have an instance of your slide container to call the function constructView().
   */
    ngAfterViewInit() {
        SlideContainer.constructView();
    }
}
@leocaseiro
Copy link
Contributor Author

leocaseiro commented Jun 9, 2016

Update

I've realized that the property angular it's on XML, not on .ts:

<SlideContainer angular="true" #slides>
    <Slide class="slide-1" *ngFor="let img of images">
        <Label [text]="img.title"></Label>
        <Image [src]="img.source"></Image>
    </Slide>
</SlideContainer>

Now, I'm trying to get my instance of SlideContainer with nativeElement:

import {Component, ElementRef, ViewChild} from '@angular/core';
import {registerElement} from "nativescript-angular/element-registry";

registerElement("SlideContainer", () => require("nativescript-slides").SlideContainer);

export class SlideDemoComponent {

    @ViewChild("slides") slides: ElementRef;

    ngAfterViewInit() {    
        let SlidesXml = this.slides.nativeElement;
        SlidesXml.constructView();
    }
}

However, I'm getting the follow error:

 file:///app/tns_modules/nativescript-slides/nativescript-slides.js:240:35: JS ERROR TypeError: undefined is not an object (evaluating '_this.currentPanel.panel')

@leocaseiro
Copy link
Contributor Author

PS: I can see all properties on my SlidesXml. For example:

console.log(SlidesXml._angular);
console.log(SlidesXml.direction);

@leocaseiro
Copy link
Contributor Author

leocaseiro commented Jun 9, 2016

I've got it!

It forgot to register the Slide element.

Here I'm going to post a full example for reference and I'll also link to the docs, so will help others:

import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {registerElement} from "nativescript-angular/element-registry";

registerElement("Slide", () => require("nativescript-slides").Slide);
registerElement("SlideContainer", () => require("nativescript-slides").SlideContainer);

@Component({
    selector: 'slidedemo',
    template: `
    <SlideContainer angular="true" #slides>
        <Slide *ngFor="let img of images">
            <Label [text]="img.title"></Label>
            <Image [src]="img.source"></Image>
        </Slide>
    </SlideContainer>
    `
})
export class SlideDemoComponent implements OnInit {

    public images: Array<any> = [];

    @ViewChild("slides") slides: ElementRef;

    ngOnInit() {
        this.images.push(
            {
                title: 'Sports',
                source: 'res://300x300.jpg'
            }
        );
        this.images.push(
            {
                title: 'Cats',
                source: 'res://Default.png'
            }
        );
        this.images.push(
            {
                title: 'Food',
                source: 'res://Icon.png'
            }
        );
    }

    ngAfterViewInit() {
        let SlidesXml = this.slides.nativeElement;
        SlidesXml.constructView();
    }
}

@timricker
Copy link

@leocaseiro thanks for figuring this out for angular2, is there anything else outside of the code above you had to do to get it working? I simply can't seem to get the Slide of SlideContainer to initialize using your code after installing the nativescript-slides package from npm to my project. If you were able to share more of a working example I would be extremely appreciative!

@leocaseiro
Copy link
Contributor Author

HI @timricker, you must have a page only for your slides.

Could you please read the issue #42, especially this comment?

I'll eventually post a demo app when I get more free time.

@timricker
Copy link

timricker commented Jun 29, 2016

Thanks @leocaseiro, I was able to get it working within a child route as you suggested, though this isn't really ideal for my project as the slides are needed on the main page of the app so will need to find a proper fix. I might dig in and see what I can uncover...

@leocaseiro
Copy link
Contributor Author

A hackish way would be navigating to your child route programmatically and remove the back button.

It's not the ideal, but temporary should save your day :D

Please, let us know if you find something that would work on the homepage in a good and not hackish way.

I shelved this for the time being...thanks

@JoshDSommer
Copy link
Owner

out of curiosity which version of Angular and NativeScript you two running

@timricker
Copy link

@TheOriginalJosh Angular 2.0.0-rc.1 & NativeScript 2.0.0. I haven't had a chance yet to investigate - any thoughts on your side as to possible cause?

@darmie
Copy link

darmie commented Oct 24, 2016

I tried to follow up on this issue and see if solutions provided would work for my project, unfortunately, my screen is now blank.

This is my sample xml

<Slides:SlideContainer id="slides" pageIndicators="true" angular="true" #slides>
  <Slides:Slide >
      <StackLayout>
        <Image src="~/assets/logo_stack-login4.png" scale="aspectFit"  horizontalAlignment="center"></Image>
        <GridLayout row="0" col="0" rows="auto auto auto auto auto">
          <DockLayout class="textBox" col="0" row="1">
            <GridLayout row="0" col="0" rows="auto auto">
              <Label row="1" col="0" class="ion" [text]="person"></Label>
              <TextField  row="1" col="1" id="email" hint="Email Address" keyboardType="email" autocorrect="false" autocapitalizationType="none"></TextField>
            </GridLayout>
          </DockLayout>
          <DockLayout class="textBox" col="0" row="2">
            <GridLayout row="0" col="0" rows="auto auto">
              <Label col="0" row="1" class="ion" [text]="padlock"></Label>
              <TextField col="1" row="2" id="password" hint="Password" secure="true"></TextField>
            </GridLayout>
          </DockLayout>
          <DockLayout col="0" row="3">
            <Button class="submit-button" text="Login"></Button>
          </DockLayout>
        </GridLayout>

      </StackLayout>
  </Slides:Slide>
  <Slides:Slide >
      <StackLayout>
        <Image src="~/assets/logo_stack-login4.png" scale="aspectFit"  horizontalAlignment="center"></Image>
        <GridLayout row="0" col="0" rows="auto auto auto auto auto">
          <DockLayout class="textBox" col="0" row="1">
            <GridLayout row="0" col="0" rows="auto auto">
              <Label row="1" col="0" class="ion" [text]="person"></Label>
              <TextField  row="1" col="1" id="email" hint="Email Address" keyboardType="email" autocorrect="false" autocapitalizationType="none"></TextField>
            </GridLayout>
          </DockLayout>
          <DockLayout class="textBox" col="0" row="2">
            <GridLayout row="0" col="0" rows="auto auto">
              <Label col="0" row="1" class="ion" [text]="padlock"></Label>
              <TextField col="1" row="2" id="password" hint="Password" secure="true"></TextField>
            </GridLayout>
          </DockLayout>
          <DockLayout col="0" row="3">
            <Button class="submit-button" text="Login"></Button>
          </DockLayout>
        </GridLayout>

      </StackLayout>
  </Slides:Slide>
</Slides:SlideContainer>

my login.component.ts

import {Component, ElementRef, OnInit, ViewChild} from "@angular/core";
import { Page } from "ui/page";
import textField = require("ui/text-field");
import view = require("ui/core/view");
import {Color} from "color";
import app = require("application");
import platform = require("platform");
import observable = require("data/observable");
//import {TNSFontIconService, TNSFontIconPipe} from 'nativescript-ng2-fonticon';
import * as slides from 'nativescript-slides/nativescript-slides'
import {registerElement} from "nativescript-angular/element-registry";

registerElement("Slide", () => require("nativescript-slides").Slide);
registerElement("SlideContainer", () => require("nativescript-slides").SlideContainer);

@Component({
  selector: "my-app",
  templateUrl: "templates/login.component.html",
  styleUrls: ["./templates/login.css"]
  //pipes: [TNSFontIconPipe]
})

export class LoginComponent implements OnInit{
  public padlock;
  public person;
  @ViewChild("slides") slides: ElementRef;
  constructor(private page: Page) {}
  ngOnInit() {
      this.page.actionBarHidden = true;
      this.page.backgroundSpanUnderStatusBar = true;


      this.padlock = String.fromCharCode(0xf392)
      this.person = String.fromCharCode(0xf3a0)

      this.page.backgroundImage = "~/assets/BackgroundLogin_dull.jpg";

    }
    ngAfterViewInit() {
        let SlidesXml = this.slides.nativeElement;
        SlidesXml.constructView();
        //var color = new Color("#CCCCCC").android;


        //Email
        /*var email = <textField.TextField>this.page.content.getViewById("email");
        email.backgroundColor = new Color("transparent");
        email.android.setHintTextColor(color);

        //Password
        var pass = <textField.TextField>this.page.content.getViewById("password");
        pass.android.setHintTextColor(color);
        pass.backgroundColor = new Color("transparent");*/
    }
}

Error

JS: EXCEPTION: Error in ./LoginComponent class LoginComponent_Host - inline template:0:0 caused by: Cannot read property 'nativeElement' of undefined
JS: ORIGINAL EXCEPTION: Cannot read property 'nativeElement' of undefined
JS: ORIGINAL STACKTRACE:
JS: TypeError: Cannot read property 'nativeElement' of undefined
JS:     at LoginComponent.ngAfterViewInit (/data/data/org.nativescript.Bau/files/app/controllers/login.component.js:20:36)
JS:     at DebugAppView._View_LoginComponent_Host0.detectChangesInternal (LoginComponent_Host.ngfactory.js:34:65)
JS:     at DebugAppView.AppView.detectChanges (/data/data/org.nativescript.Bau/files/app/tns_modules/@angular/core/bundles/core.umd.js:9325:18)
JS:     at DebugAppView.detectChanges (/data/data/org.nativescript.Bau/files/app/tns_modules/@angular/core/bundles/core.umd.js:9430:48)
JS:     at DebugAppView.AppView.detectContentChildrenChanges (/data/data/org.nativescript.Bau/files/app/tns_modules/@angular/core/bundles/core.umd.js:9343:23)
JS:     at DebugAppView.AppView.detectChangesInternal (/data/data/org.nativescript.Bau/files/app/tns_modules/@angular/core/bundles/core.umd.js:9335:18)
JS:     at DebugAppView.AppView.detectChanges (/data/data/org.nativescript.Bau/files/app/tns_modules/@angular/core/bundles/core.umd.js:9325:18)
JS:     at DebugAppView.detectChanges (/data/data/org.nativescript.Bau/files/app/tns_modules/@angular/core/bundles/core.umd.js:9430:48)
JS:     at DebugAppView.AppView.detectViewChildrenChanges (/data/data/org.nativescript.Bau/files/app/tns_modules/@angular/core/bundles/core.umd.js:9351:23)
JS:     at DebugAppView._View_AppComponent_Host0.detectChangesInternal (AppComponent_Host.ngfactory.js:31:8)
JS: ERROR CONTEXT:
JS: [object Object]
JS: Error: Error in ./LoginComponent class LoginComponent_Host - inline template:0:0 caused by: Cannot read property 'nativeElement' of undefined

@heese
Copy link

heese commented Nov 25, 2016

I am using nativescript+angular combined with ngFor: It seems that the slider is not working if it is on the first page shown (e.g., shown immediately after splash screen). I used the example provided by leocaseiro.

@leocaseiro
Copy link
Contributor Author

Hi @heese. Make sure you import NativeScriptModule to use *ngFor

@heese
Copy link

heese commented Nov 25, 2016

Hi @leocaseiro, I am glad that someone watches this thread.

Yesterday, I was a bit lazy and did not describe the issue well.

The directive *ngFor is working and is not the problem. I have created an example which illustrates the problem [1] -- at least on my machine :-)

If SlideComponent is the first screen (line 16 of app.module.ts redirects to /slide) then all content of the slides is rendered (overlapping) but does not slide at all. However, if BarComponent is the first screen (line 16 of app.module.ts redirects to /button) and you click the Button to get to /slide then the slider works correctly.

Maybe, you can figure out what is wrong with my example.

[1] https://drive.google.com/file/d/0ByKUAQ8GY5GNaHFER2Q2VzdjM0E/view

@heese
Copy link

heese commented Nov 26, 2016

Without success I spend quite some time to use the slides module in the following scenario (ns + angular): The data shown in the slide container is loaded dynamically (via HTTP request to a server), e.g., it is not available when ngAfterViewInit is called.

I tried to use the event loaded to create the slides dynamically which does not work. I used the same code I used in ngAfterViewInit (in this case I even assumed static slides):

let SlidesXml = this.slides.nativeElement;
SlidesXml.addChild(this.getSlide("res://icon"));
SlidesXml.addChild(this.getSlide("res://icon"));
SlidesXml.constructView();

It seems that it is too late and the views are not constructed properly. It renders the items but the slide container seems not to be set up properly.

I managed to initialise the slide container with placeholders and replace its content with the data retrieved from the server. Unfortunately, I don't know in advance how many slides I need. It does also not work to create placeholders first and remove unneeded slides later. The removed slides are still there but blank, e.g., users would see blank slides when scrolling through the slides.

Is there a way to add slides much later, e.g., after ngAfterViewInit has been executed?

@enricodeleo
Copy link

Me too, I am spending quite a bunch of time trying to figure out how to make this module work on Angular 2.

I tried @leocaseiro approach but could not make this work neither with latest version from npm (2.2.4) neither with latest stable release from github (2.1.6).

I also tried importing the typescript version of the module like this:

import { SlideContainer, Slide } from 'nativescript-slides/nativescript-slides';

// Register custom elements from nativescript-slides plugin
registerElement( 'CarouselItem', () => Slide );
registerElement( 'Carousel', () => SlideContainer );

but got the same problem.

The problem occurs both for main/root page and child page.

Some log:

with template root element of the page:

file:///app/tns_modules/ui/content-view/content-view.js:37:91: JS ERROR Error: More than one layout child inside a ContentView

with template inside a <StackLayout> or <GridLayout>:

CONSOLE ERROR file:///app/tns_modules/@angular/core/bundles/core.umd.js:3014:36: [object Object] CONSOLE ERROR file:///app/tns_modules/nativescript-angular/zone.js/dist/zone-nativescript.js:344:22: Error: Error in ./HomeComponent class HomeComponent_Host - inline template:0:0 caused by: SlidesXml.constructView is not a function. (In 'SlidesXml.constructView()', 'SlidesXml.constructView' is undefined)

@JoshDSommer
Copy link
Owner

I've started working on a angular 2 version of this plugin since implementing it as is has been a pain. You can check it out here : https://www.npmjs.com/package/nativescript-ng2-slides

@JoshDSommer JoshDSommer reopened this Dec 11, 2016
@enricodeleo
Copy link

Can't wait! I'm going to test the new plugin like right now :)

@heese
Copy link

heese commented Dec 13, 2016

Works well. Thank you for spending your time on creating an Angular module.

Is it possible to add all slides at a later point of time (e.g., wait for an HTTP request to return)? At the moment it seems that I have to have the data for creating the slides in ngInit (at the moment I use a simple array of strings). If I am creating the data in ngAfterViewInit it is already to late as you are using this hook for setting up the slides.

Here is a simplified example to illustrate the situation.

this.userService.getProfile().subscribe(
    data => {
        this.slidesBackingArray.push("Panel 1", "Panel 2", "Panel 3");
    });

@JoshDSommer
Copy link
Owner

@heese hmm, that's something I'll keep in mind with the new angular 2 version of the slides. Seems like a pretty common use case. if you have any ideas i'm open to suggestions too

@JoshDSommer
Copy link
Owner

@enricodeleo Thanks man! much appreciated, please let me know of any issues or errors you encounter.

@heese
Copy link

heese commented Jan 4, 2017

I have created a new ticket in the project nativescript-ng2-slides: JoshDSommer/nativescript-ngx-slides#3

@rkapps
Copy link

rkapps commented Jan 24, 2017

Basic slide functionality seems to be working okay. But when i put a listview or a radlistview in the slide, i can't seem to be able to swipe on the listview or radlistview. The same swiping is available when i add the listview or radlistview in a tabview

@rkapps
Copy link

rkapps commented Jan 24, 2017

Here is the example where the swipe is not working.

<slides pageIndicators="true" >
    <slide class="slide-1" *ngFor="let dataArray of myDataArray">
        <Label text="{{dataArray.title}}"></Label>
        <GridLayout >
            <RadListView [items]="dataArray.items">
                <template tkListItemTemplate let-item="item">
                    <StackLayout orientation="vertical">
                        <Label [text]="item"></Label>
                    </StackLayout>
                </template>
            </RadListView>
        </GridLayout>
    </slide>
</slides>

@leocaseiro
Copy link
Contributor Author

leocaseiro commented Jun 9, 2017

I apologise for who is subscribed in this issue.

Charles Bonet contacted me by email in regards this issue.
Sorry Charles Bonet, I've got your email wrong and I couldn't reply to you, so I though I should post the messages up here:

From Charles Bonet

Hello,
I contact you because you posted on #37 (comment). I tried to implement your code but all i have now is a blank page without errors. Im using nativescript-slides 2.2.8+ and my nativescript version is 3.00 and we are using angular4. I searched a lot on this subject and i've been hardstuck for 2 days on this seemingly trivial issue.. I also tried to switch to nativescript-ngx-slides because it seems to be indicated for angular+ stuff but i cannot make it work either.

Can you let me know if your code is working or not atm ? I just dont want to spend too much time if there's nothing i can do to make it work for now.

Many thanks, have a good day

My answer:

Hi, I'm sorry I haven't used it a long time. Sorry about that, I'm afraid I can't help.

It shouldn't be working in regards to NgModules, this code is really old, we didn't have ngModules at that point, so was much easier to integrate JS modules into angular. I haven't looked into {N} since NgModules, I've been busy with web apps.

I suggest you open an issue on https://github.com/TheOriginalJosh/nativescript-ngx-slides which is the most indicated for angular.
Josh has always been really helpful, I'm pretty sure he'll come with something for you.

Hope you can get it working. Have a nice day.

PS: I'm closing this issue in regards to the https://github.com/TheOriginalJosh/nativescript-ngx-slides
Any angular related should be there.

@JoshDSommer
Copy link
Owner

Np sounds good @leocaseiro, thanks man

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants