Custom component with ion slide

I try ionic2 beta9 and try to create a custom component with an ion slide, but I get an error.

Parent component

<ion-content class="home" padding>    
  <ion-slides loop="true">
    <slide-item *ngFor="let image of [1,2,3,4,5]" [imgIdx]="image"></slide-item>
  </ion-slides>
</ion-content>

Custom Slide Component

<ion-slide>
        <div class="bcontent">
            <div class="bimg">
                <img data-src="images/slide{{imgIdx}}.jpeg">
            </div>
            <p class="info">My text</p>
        </div>
</ion-slide>

slide item.ts

@Component({
  selector: 'slide-item',
  templateUrl: 'build/components/slide-item/slide-item.html',
  directives: [Slides, Slide]
})
export class SlideItem {

  @Input()
  imgIdx: number;

  constructor() {
    console.log("SlideItem::constructor...imgIdx="+this.imgIdx);
  }
}

I get the following error:

zone.js: 461

Unhandled Promise rejection: Template parse errors:
No provider for Slides ("
  for more info on Angular 2 Components.
-->
[ERROR ->]<ion-slide>
        <div class="bcontent">
            <div class="bimg">
"): SlideItem@6:0 

; Zone: angular; Task: Promise.then; Value:

BaseException {message: "Template parse errors:↵No provider for Slides ("↵ …↵            <div class="bimg">↵"): 
SlideItem@6:0", stack: "Error: Template parse errors:↵No provider for Slid…ndroid_asset/www/build/js/app.bundle.js:30622:41)"}message: 
"Template parse errors:↵No provider for Slides ("for more info on Angular 2 Components.↵-->↵[ERROR ->]<ion-slide>↵        <div class="bcontent">↵            <div class="bimg">↵"): SlideItem@6:0"

stack: "Error: Template parse errors:↵No provider for Slides ("for more info on Angular 2 Components.↵-->↵[ERROR ->]<ion-slide>↵        <div class="bcontent">↵            <div class="bimg">↵"): SlideItem@6:0↵    at new BaseException (file:///android_asset/www/build/js/app.bundle.js:1760:23)↵    at TemplateParser.parse (file:///android_asset/www/build/js/app.bundle.js:16401:19)↵    at file:///android_asset/www/build/js/app.bundle.js:14643:64↵    at ZoneDelegate.invoke (file:///android_asset/www/build/js/zone.js:323:29)↵    at Object.onInvoke (file:///android_asset/www/build/js/app.bundle.js:30631:41)↵    at ZoneDelegate.invoke (file:///android_asset/www/build/js/zone.js:322:35)↵    at Zone.run (file:///android_asset/www/build/js/zone.js:216:44)↵    at file:///android_asset/www/build/js/zone.js:571:58↵    at ZoneDelegate.invokeTask (file:///android_asset/www/build/js/zone.js:356:38)↵    at Object.onInvokeTask (file:///android_asset/www/build/js/app.bundle.js:30622:41)"__proto__: ErrorconsoleError @ zone.js:461_loop_1 @ zone.js:490drainMicroTaskQueue @ zone.js:494ZoneTask.invoke @ zone.js:426
+4
source share
1 answer

Why it does not work

I do not think that this is possible with the current design of the components of slides and slides. ion-slidemust be a child ion-slides, and it must be able to find its parent slides inside the same template.

Here is the source:

@Component({
  selector: 'ion-slide',
  template: '<div class="slide-zoom"><ng-content></ng-content></div>',
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
})
export class Slide {

  ele: HTMLElement;

  @Input() zoom: any;

  constructor(
    elementRef: ElementRef,
    @Host() public slides: Slides
  ) {
    this.ele = elementRef.nativeElement;
    this.ele.classList.add('swiper-slide');

    slides.rapidUpdate();
  }

  ngOnDestroy() {
    this.slides.rapidUpdate();
  }
}

, Slides , Slide Slides . @Host.

ion-slide , Slides, Slide.

, :

  • Slides Slides, Slides /
  • - .

slides.ts:

@Component({
  selector: 'ion-slide',
  template: '<div class="slide-zoom"><ng-content></ng-content></div>',
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
})
export class Slide {

  ele: HTMLElement;

  @Input() zoom: any;

  constructor(
    elementRef: ElementRef
  ) {
    this.ele = elementRef.nativeElement;
    this.ele.classList.add('swiper-slide');
  }
}

:

@Component({
  selector: 'slide-item',
  templateUrl: 'slide-item.html',
})
export class SlideItem {

  @Input()
  imgIdx: number;

  constructor(elementRef: ElementRef) {
    console.log("SlideItem::constructor...imgIdx="+this.imgIdx);
    elementRef.nativeElement.classList.add('swiper-slide');
  }
}

, , , Slides / .

, / , , . (-) .

2

Slide . ( ion-slide):

@Component({
  selector: 'slide-item',
  templateURL: 'slite-item.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
})
export class SlideItem {

  ele: HTMLElement;

  @Input() zoom: any;
  @Input() imgIdx: number;

  constructor(
    elementRef: ElementRef
  ) {
    this.ele = elementRef.nativeElement;
    this.ele.classList.add('swiper-slide');

    console.log("SlideItem::constructor...imgIdx="+this.imgIdx)
  }
}

<div class="slide-zoom bcontent">
  <div class="bimg">
    <img data-src="images/slide{{imgIdx}}.jpeg">
  </div>
  <p class="info">My text</p>
</div>

, , Ionic. .

SO . , Angular (ComponentMetaData ), , . Slide.

export function CustomComponent(annotation: any) {
  return function (target: Function) {
    var parentTarget = Object.getPrototypeOf(target.prototype).constructor;
    var parentAnnotations = Reflect.getMetadata('annotations', parentTarget);

    var parentAnnotation = parentAnnotations[0];
    Object.keys(parentAnnotation).forEach(key => {
      if (isPresent(parentAnnotation[key])) {
        annotation[key] = parentAnnotation[key];
      }
    });
    var metadata = new ComponentMetadata(annotation);

    Reflect.defineMetadata('annotations', [ metadata ], target);
  }
}

, , .

import { Slide } from 'ionic-angular';

@CustomComponent({
  selector: 'slide-item',
  templateURL: 'slite-item.html'
})
export class SlideItem extends Slide {
  @Input() imgIdx: number;
}
0

All Articles