尝试使用角度模板使用图像填充Bootstrap轮播

时间:2018-06-24 12:36:12

标签: angular typescript bootstrap-4

我正在尝试用屏幕截图动态填充引导轮播。除了实际切换屏幕截图之外,其他所有功能都可以正常工作。我发现这是由<screenshots>标记按角度放置引起的。如果我手动删除此<screenshots>,它将正常工作。有没有办法以编程方式执行此操作?还是我的方法不好/错误?

project-template.component.html(轮播部分)

<div id="test" class="carousel slide" data-ride="carousel">
    <div class="carousel-inner">
      <template #screenshots></template>
    </div>
    <a class="carousel-control-prev" href="#test" role="button" data-slide="prev">
      <span class="carousel-control-prev-icon" aria-hidden="true"></span>
      <span class="sr-only">Previous</span>
    </a>
    <a class="carousel-control-next" href="#test" role="button" data-slide="next">
      <span class="carousel-control-next-icon" aria-hidden="true"></span>
      <span class="sr-only">Next</span>
    </a>
</div>

project-template.component.ts(轮播部分)

import { Component, OnInit, ViewChild, ViewContainerRef, ComponentFactoryResolver, ComponentFactory, ComponentRef, Input, Output, EventEmitter } from '@angular/core';
import { Router } from '@angular/router';
import { ScreenshotsComponent } from './screenshots/screenshots.component';

@Component({
  selector: 'app-project-template',
  templateUrl: './project-template.component.html',
  styleUrls: ['./project-template.component.css']
})
export class ProjectTemplateComponent {

  @Input() screenshots: Array<Object>;
  @Output() output = new EventEmitter();


  @ViewChild("screenshots", { read: ViewContainerRef }) containerScreenshots;
  componentRefScreenshots: ComponentRef<ScreenshotsComponent>;

  constructor(private resolver: ComponentFactoryResolver) { }

  ngOnInit() {
    this.containerScreenshots.clear();

    for(let i = 1; i < this.screenshots[0]["count"] + 1; i++){
      const factory: ComponentFactory<ScreenshotsComponent> = this.resolver.resolveComponentFactory(ScreenshotsComponent);
      this.componentRefScreenshots = this.containerScreenshots.createComponent(factory);
      let put = this.componentRefScreenshots.instance
      put.output.subscribe(event => console.log(event));
      if(i == 1){
        put.ac = " active"
      }
      put.number = i
      put.project = this.screenshots[0]['project'] as string;
      put.projectType = this.screenshots[0]['project-type'] as string;
    }

  }

}

screenshots.component.html

<div class="carousel-item{{ac}}">
  <img class="d-block w-100 image" src="../assets/{{projectType}}/{{project}}/Screenshot-{{number}}.png" alt="{{number}} slide"
    style="max-width: 15%; max-height: 15%;">
</div>

screenshots.component.ts

import { Component, OnInit, Output, Input, EventEmitter } from '@angular/core';

@Component({
  selector: 'screenshots',
  templateUrl: './screenshots.component.html',
  styleUrls: ['./screenshots.component.css']
})
export class ScreenshotsComponent implements OnInit {

  @Input() projectType: string = "loading...";
  @Input() project: string = "loading...";
  @Input() number: number = -1;
  @Input() ac: string = "";
  @Output() output = new EventEmitter();

  constructor() { }

  ngOnInit() {

  }

}

结果:

<div _ngcontent-c1="" class="carousel slide" data-ride="carousel" id="test">
  <div _ngcontent-c1="" class="carousel-inner">
    <template _ngcontent-c1=""></template>
    <screenshots _nghost-c6="">
      <div _ngcontent-c6="" class="carousel-item active">
        <img _ngcontent-c6="" class="d-block w-100 image" style="max-width: 15%; max-height: 15%;" src="../assets/android-projects/school-diary/Screenshot-1.png"
          alt="1 slide">
      </div>
    </screenshots>
    <screenshots _nghost-c6="">
      <div _ngcontent-c6="" class="carousel-item">
        <img _ngcontent-c6="" class="d-block w-100 image" style="max-width: 15%; max-height: 15%;" src="../assets/android-projects/school-diary/Screenshot-2.png"
          alt="2 slide">
      </div>
    </screenshots>
    <screenshots _nghost-c6="">
      <div _ngcontent-c6="" class="carousel-item">
        <img _ngcontent-c6="" class="d-block w-100 image" style="max-width: 15%; max-height: 15%;" src="../assets/android-projects/school-diary/Screenshot-3.png"
          alt="3 slide">
      </div>
    </screenshots>
    <screenshots _nghost-c6="">
      <div _ngcontent-c6="" class="carousel-item">
        <img _ngcontent-c6="" class="d-block w-100 image" style="max-width: 15%; max-height: 15%;" src="../assets/android-projects/school-diary/Screenshot-4.png"
          alt="4 slide">
      </div>
    </screenshots>
    <screenshots _nghost-c6="">
      <div _ngcontent-c6="" class="carousel-item">
        <img _ngcontent-c6="" class="d-block w-100 image" style="max-width: 15%; max-height: 15%;" src="../assets/android-projects/school-diary/Screenshot-5.png"
          alt="5 slide">
      </div>
    </screenshots>
    <screenshots _nghost-c6="">
      <div _ngcontent-c6="" class="carousel-item">
        <img _ngcontent-c6="" class="d-block w-100 image" style="max-width: 15%; max-height: 15%;" src="../assets/android-projects/school-diary/Screenshot-6.png"
          alt="6 slide">
      </div>
    </screenshots>
    <screenshots _nghost-c6="">
      <div _ngcontent-c6="" class="carousel-item">
        <img _ngcontent-c6="" class="d-block w-100 image" style="max-width: 15%; max-height: 15%;" src="../assets/android-projects/school-diary/Screenshot-7.png"
          alt="7 slide">
      </div>
    </screenshots>
    <screenshots _nghost-c6="">
      <div _ngcontent-c6="" class="carousel-item">
        <img _ngcontent-c6="" class="d-block w-100 image" style="max-width: 15%; max-height: 15%;" src="../assets/android-projects/school-diary/Screenshot-8.png"
          alt="8 slide">
      </div>
    </screenshots>
  </div>
  <a _ngcontent-c1="" class="carousel-control-prev" data-slide="prev" href="#test" role="button">
    <span _ngcontent-c1="" aria-hidden="true" class="carousel-control-prev-icon"></span>
    <span _ngcontent-c1="" class="sr-only">Previous</span>
  </a>
  <a _ngcontent-c1="" class="carousel-control-next" data-slide="next" href="#test" role="button">
    <span _ngcontent-c1="" aria-hidden="true" class="carousel-control-next-icon"></span>
    <span _ngcontent-c1="" class="sr-only">Next</span>
  </a>
</div>

1 个答案:

答案 0 :(得分:1)

在我看来,您正在尝试使用 bootstrap ,而不是 ngx-bootstrap 。 我认为您最好使用后者,因为它更适合角度:)

第二,我不明白您为什么尝试使用“复杂的” ComponentFactory等来强制执行组件创建过程。有什么理由吗?只是因为如果没有,我宁愿使用 ngx-bootstrap 文档中的动态幻灯片示例:

https://valor-software.com/ngx-bootstrap/#/carousel#dynamic-slides

因此,基本上,模板文件中只有一个for循环(ngFor),该文件会动态生成幻灯片,具体取决于绑定输入中有多少幻灯片数据。 carousel标签具有activeSlide属性,该属性可以双向绑定,因此您可以轻松控制所需的幻灯片索引处于活动状态。

编辑: 如果唯一的问题是如何删除screenshots组件的包装标签,则可以执行以下操作:

  1. 调整屏幕截图组件以使其也可以用作指令:

代替

selector: 'screenshots',

使用

selector: 'screenshots, [screenshots-directive]',
  1. 用法

代替

<div class="carousel-inner">
    <template #screenshots></template>
</div>

如前所述编写for循环:

<div class="carousel-inner">
  <div class="carousel-item" *ngFor="let screenshot of screenshots; 
       let i = index" screenshots-directive [number]="i" [project]="screenshot.project">
  </div>
</div>

请注意,我从carousel-item组件中删除了screenshots格。这是必需的,因为需要将for循环添加到html标记中。通常,当您要使用for循环但不希望显示for循环的容器时,可以使用ng-templateng-container标签。但是,它似乎无法与screenshots-directive之类的指令一起使用,我不知道为什么。