如何为ngFor中的每个元素显示模式?

时间:2019-02-18 15:50:56

标签: angular typescript ngfor

我知道之前曾有人问过这个问题,我已经尝试了所提出的解决方案,但对我来说都没有用。

所以我有一个包含书单的仪表板,并且我创建了一个模式,当单击该书以显示书详细信息时会显示

模态工作正常!问题是我对所有书籍都使用相同的模式!就像我传递给模式的数据并没有随着ngFor的迭代而发生变化(卡在第一次迭代中)

这是我的component.html

<div class="container">
  <div class="row">
    <div class="col-md-3" *ngFor="let p of (Publications | sort: pubSort)">
      <figure class="card card-product">
        <div class="img-wrap">
          <img
            src="{{ p.URL_couv }}"
            alt="{{ p.id }}"
            data-toggle="modal"
            data-target="#p"
          />
        </div>
        <figcaption class="info-wrap">
          <h6 class="title text-dots">{{ p.titre }} n° {{ p.numero }}</h6>
          <div class="action-wrap">
            <div class="price-wrap">
              {{ p.date_parution }}
            </div>
            <!-- price-wrap.// -->
          </div>
          <!-- action-wrap -->
        </figcaption>
      </figure>
      <!-- MODAL -->
      <!-- Modal -->
      <div
        class="modal fade bd-example-modal-lg"
        id="p"
        tabindex="-1"
        role="dialog"
        aria-labelledby="exampleModalLongTitle"
        aria-hidden="true"
      >
        <div class="modal-dialog modal-lg" role="document">
          <div class="modal-content">
            <div class="modal-header">
              <h5 class="modal-title" id="exampleModalLongTitle">
                {{ p.titre }} n° {{ p.numero }}
              </h5>

              <button
                type="button"
                class="close"
                data-dismiss="modal"
                aria-label="Close"
              >
                <span aria-hidden="true">&times;</span>
              </button>
            </div>
            <div class="modal-body">
              
            </div>
            <div class="modal-footer">
              <button
                type="button"
                class="btn btn-secondary"
                data-dismiss="modal"
              >
                Fermer
              </button>
              <button type="button" class="btn btn-primary">
                Enregistrer les changements
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
<!-- col // -->

Mon fichier TS:

import { Component, OnInit, Inject } from "@angular/core";
import { Publication } from "../models/publication.model";
import { PubsService } from "../services/pubs.service";
import { Router } from "@angular/router";
import { Subscription } from "rxjs";
import { DOCUMENT } from "@angular/platform-browser";

@Component({
  selector: "app-pub-list",
  templateUrl: "./pub-list.component.html",
  styleUrls: ["./pub-list.component.css"]
})
export class PubListComponent implements OnInit {
  Publications: Publication[];
  pubs: Publication[] = [];
  pubsSubscription: Subscription;
  pubSort: string = "";
  private dom: Document;

  constructor(
    private pubService: PubsService,
    private router: Router,
    @Inject(DOCUMENT) dom: Document
  ) {
    this.dom = dom;
  }

  details() {}

  // Convert Timestamp to Date
  timeConverter(t) {
    var a = new Date(t);
    var today = new Date();
    var yesterday = new Date(Date.now() - 86400000);
    var months = [
      "Janvier",
      "Février",
      "Mars",
      "Avril",
      "Mai",
      "Juin",
      "Juillet",
      "Août",
      "Sep",
      "Oct",
      "Nov",
      "Dec"
    ];
    var year = a.getFullYear();
    var month = months[a.getMonth()];
    var date = a.getDate();
    var hour = a.getHours();
    var min = a.getMinutes();
    if (a.setHours(0, 0, 0, 0) == today.setHours(0, 0, 0, 0))
      return "Aujourd'hui ";
    else if (a.setHours(0, 0, 0, 0) == yesterday.setHours(0, 0, 0, 0))
      return "Hier";
    else if (year == today.getFullYear()) return date + " " + month;
    else return date + " " + month + " " + year;
  }


  // ngOnInit exexutes each time the component is charged
  ngOnInit() {
    this.pubsSubscription = this.pubService.pubsSubject.subscribe(
      (pubs: Publication[]) => {
        let a = Object.entries(pubs);
        if (a != undefined) {
          for (let prop of a) {
            let key = prop[0];
            let pub = prop[1];
            var out = Object.keys(pub).map(function(data) {
              return [data, pub[data]];
            });
            if (out[3] != undefined && out[7] != undefined) {
              // create a Publication object
              let a: Publication = new Publication(
                key,
                out[0][1],
                out[1][1],
                out[2][1],
                out[3][1],
                out[4][1],
                out[5][1],
                out[6][1],
                out[7][1]
              );
              // add the publication object to object list
              this.pubs.push(a);
            }
          }
        }
        // Sort publications by "Date parution "
        this.pubs.sort((a, b) =>
          a.date_parution < b.date_parution
            ? 1
            : b.date_parution < a.date_parution
            ? -1
            : 0
        );
        // convert date parution to date
        for (let el of this.pubs) {
          el.date_parution = this.timeConverter(el.date_parution);
        }
        // send back the publications to HTML
        this.Publications = this.pubs;
      }
    );
    this.pubService.emitTitres();
  }
}

谢谢

2 个答案:

答案 0 :(得分:1)

我敢打赌,排序管道是纯净的。因此,当输入参考值未更改时,它不会触发。拆下管道并检查。

quote:Angular executes a pure pipe only when it detects a pure change to the input value. A pure change is either a change to a primitive input value (String, Number, Boolean, Symbol) or a changed object reference (Date, Array, Function, Object).

因此,当您要将对象传递给纯管道时,这是一种很好的做法。

编辑:抱歉,我把问题弄错了。看来您有一个命名问题。

 data-target="#p"

id="p"的静态值将为'p',而不是您期望从ngFor获得的动态值。

要使其动态,请使用 [attr.data-target] =“'#'+ p” [attr.id] =“ p”

答案 1 :(得分:0)

尝试使用ngfor中的异步管道

  

https://angular.io/api/common/AsyncPipe

*ngFor="p of publications | async"