Ionic2 带有离子载玻片的自定义组件

Ionic2 带有离子载玻片的自定义组件,ionic2,Ionic2,我正在尝试ionic2 beta9,并尝试使用ion slide创建自定义组件,但我遇到了一个错误 父组件 我收到以下错误: zone.js:461 Unhandled Promise rejection: Template parse errors: No provider for Slides (" for more info on Angular 2 Components. --> [ERROR ->]<ion-slide> <div cl

我正在尝试ionic2 beta9,并尝试使用ion slide创建自定义组件,但我遇到了一个错误

父组件 我收到以下错误: 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 
未处理的承诺拒绝:模板分析错误:
幻灯片没有提供程序(“
有关Angular 2组件的详细信息。
-->
[错误->]
"): SlideItem@6:0 
);区域:角度;任务:承诺;价值:

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
BaseException{消息:“模板分析错误:↵幻灯片没有提供程序(“↵ …↵            ↵"): 
SlideItem@6:0”,堆栈:“错误:模板分析错误:↵没有提供以下内容的提供商…ndroid_asset/www/build/js/app.bundle.js:30622:41)}消息:
“模板分析错误:↵幻灯片没有提供程序(“↵  有关Angular 2组件的详细信息。↵-->↵[错误->]↵        ↵            ↵"): SlideItem@6:0"
堆栈:“错误:模板分析错误:↵幻灯片没有提供程序(“↵  有关Angular 2组件的详细信息。↵-->↵[错误->]↵        ↵            ↵"): SlideItem@6:0↵    在纽约例外(file:///android_asset/www/build/js/app.bundle.js:1760:23)↵    在TemplateParser.parse(file:///android_asset/www/build/js/app.bundle.js:16401:19)↵    在file:///android_asset/www/build/js/app.bundle.js:14643:64↵    在ZoneDelegate.invoke(file:///android_asset/www/build/js/zone.js:323:29)↵    在Object.onInvoke(file:///android_asset/www/build/js/app.bundle.js:30631:41)↵    在ZoneDelegate.invoke(file:///android_asset/www/build/js/zone.js:322:35)↵    在Zone.run(file:///android_asset/www/build/js/zone.js:216:44)↵    在file:///android_asset/www/build/js/zone.js:571:58↵    在ZoneDelegate.invokeTask(file:///android_asset/www/build/js/zone.js:356:38)↵    在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

为什么它不起作用

我认为目前幻灯片和幻灯片组件的设计是不可能的。
ion幻灯片
必须是
ion幻灯片
元素的子元素,并且必须能够在同一模板中找到其父幻灯片

以下是消息来源:

@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();
  }
}
和您的幻灯片项目:

@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');
  }
}
我说这是一个部分解决方案,因为您必须修改离子源,并且现在您必须在添加/删除幻灯片时手动调用update
Slides
update

我确实在进一步修改离子源以维护添加/删除幻灯片(包括您的自定义幻灯片容器)的自动更新方面取得了一些进展。但与下面的选项相比,它看起来并不值得

部分解决方案2

幻灯片的代码非常简单。您最好直接定义自己的组件(而不是包装离子幻灯片)

和模板

<div class="slide-zoom bcontent">
  <div class="bimg">
    <img data-src="images/slide{{imgIdx}}.jpeg">
  </div>
  <p class="info">My text</p>
</div>
您的模板将与前面的解决方案相同,但该类将简化为以下内容

import { Slide } from 'ionic-angular';

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

你有什么收获吗?我在ionic angular/components/Slides/Slides/Slides.js的
Slide.decorators中添加了
providers:[Slides]
,错误消失了。不过,幻灯片的渲染不正确,所以我仍在处理。
@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');
  }
}
@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>
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;
}