Heim  >  Artikel  >  Web-Frontend  >  Analyse der Kapselung der Bildlauflistenkomponente in Angular 6

Analyse der Kapselung der Bildlauflistenkomponente in Angular 6

不言
不言Original
2018-07-23 11:35:581788Durchsuche

Der Inhalt, der in diesem Artikel mit Ihnen geteilt wird, befasst sich mit der Analyse der Kapselung der Bildlauflistenkomponente in Angular 6. Er hat einen gewissen Referenzwert. Freunde in Not können sich darauf beziehen.

Vorwort

Lernen sollte ein Prozess der Kombination von input und output sein, weshalb dieser Artikel geschrieben wurde.
Bildlauflisten werden häufig in Web-APPs mit großem Bildschirm verwendet. Nach mehreren Versuchen kam ich auf eine ziemlich gute Idee.

Anforderungen

  • Der Kopfteil des Listenkopfes ist stationär, während der Tbody-Teil nach oben scrollt.

  • Nachdem das Scrollen des Tbody-Teils abgeschlossen ist, müssen die Daten aktualisiert werden. Der letzte Effekt besteht darin, alle relevanten Daten in der Datenbank in einer nach oben scrollenden Form anzuzeigen.

Analyse

Wenn die Datenmenge relativ gering ist, können wir alle Daten auf einmal herausnehmen und zum kreisförmigen Scrollen in das DOM einfügen. Tatsächlich ähnelt es dem Effekt eines Karussells.

Aber wenn viele Daten vorhanden sind, kann dies zu einem Speicherverlust führen. Natürlich können wir uns auch eine Paginierung der Listendaten vorstellen. Meine ursprüngliche Idee bestand darin, ein table als Container in die äußere Schicht von p einzufügen und dann table den Wert von top regelmäßig zu erhöhen. Wenn table zur Hälfte ausgeführt wird, fordern Sie Daten vom Backend an und erstellen Sie es dynamisch. Eine Komponente tbody wird in table eingefügt und dann wird die Komponente gelöscht, wenn die vorherige tbody nicht mehr sichtbar ist. Die Idee schien machbar, doch in der Praxis stieß sie auf Probleme. Wenn die vorherige Komponente löscht, wird die Höhe von table verringert und der Tisch fällt sofort um. Das ist offensichtlich nicht das, was wir wollen, und die Nebenwirkungen sind ziemlich schwerwiegend.

In diesem Fall habe ich tbody in zwei tables und die beiden table-Schleifen aufgeteilt. Wenn unter dem vorherigen table keine Daten vorhanden sind, beginnt das zweite table zu laufen. Wenn das erste table vollständig aus p herauskommt, setzen Sie seine Position auf das untere Ende von p zurück und aktualisieren Sie das Daten und wiederholen Sie dann die Aktionen dazwischen. Es ist etwas mühsam, es fertigzustellen, aber der Effekt ist passabel und zufriedenstellend. Das Problem ist, dass die beiden Timer instabil sind. Wenn ich eine andere Software öffne und zurückkomme, laufen die beiden Tabellen inkonsistent. Diese angeborene Krankheit setInterval ist nicht genau genug und die beiden Timer neigen zu einer schlechten Koordination.

Auf dem Heimweg von der Arbeit fiel mir schließlich eine Methode ein, die keine zwei Tische erfordert. Verwenden Sie nur einen table Timer, um nach oben zu gelangen. Wenn Sie die Hälfte geschafft haben, löschen Sie den Timer, setzen Sie die Position zurück und aktualisieren Sie die Hälfte der Daten. Das heißt, die erste Hälfte der Daten im Array wird entfernt und die aus dem Hintergrund gezogenen neuen Daten werden auf das Array gespleißt. Auf diese Weise können die Daten kontinuierlich aktualisiert werden, und tablees sieht so aus, als würden sie immer weiter steigen.

Code

scroll-table.component.html

<p class="table-container">
  <table class="head-show">
    <thead>
      <tr>
        <th style="width:12.8%;">字段1</th>
        <th style="width:12.8%;">字段2</th>
        <th>字段3</th>
        <th style="width:12.8%;">字段4</th>
      </tr>
    </thead>
  </table>
  <p class="scroller-container">
    <table #scroller class="scroller">
      <tbody>
        <tr *ngFor="let ele of tbody">
          <td style="width:12.8%;">{{ele.field01}}</td>
          <td style="width:12.8%;">{{ele.field02}}</td>
          <td><p>{{ele.field03}}</p></td>
          <td style="width:12.8%;">{{ele.field04}}</td>
        </tr>
      </tbody>
    </table>
  </p>
</p>

scroll-table.component.ts

import { Component, OnInit, ViewChild, ElementRef, Input } from '@angular/core';
import { HttpService } from '../http.service';

@Component({
  selector: 'app-scroll-table',
  templateUrl: './scroll-table.component.html',
  styleUrls: ['./scroll-table.component.scss']
})
export class ScrollTableComponent implements OnInit {
  tbody: any = [];
  @Input() url; //将地址变成组件的一个参数,也就是输入属性
  //控制滚动的元素
  @ViewChild('scroller') scrollerRef: ElementRef;
  timer: any;

  freshData: any;

  pageNow = 1;//pageNow是当前数据的页码,初始化为1

  constructor(private http: HttpService) {}

  ngOnInit() {
    //初始化拿到native
    let scroller: HTMLElement = this.scrollerRef.nativeElement;
    this.http.sendRequest(this.url).subscribe((data :any[]) => {
      
      this.tbody = data.concat(data);
    });
    //开启定时器
    this.timer = this.go(scroller);
  }

  getFreshData() {
  //每次请求数据时,pageNow自增1
    this.http.sendRequest(`${this.url}?pageNow=${++this.pageNow}`).subscribe((data:any[]) => {
      if(data.length<10) {
        //数据丢弃,pageNow重置为1
        this.pageNow = 1;
      }
      this.freshData = data;
    });
  }
  
  go(scroller) {
    var
      moved = 0,
      step = -50,
      timer = null,
      task = () => {
        let style = document.defaultView.getComputedStyle(scroller, null);
        let top = parseInt(style.top, 10);
        if (moved < 10) {
          if(moved===0) {
            this.getFreshData();
          }
          scroller.style.transition = "top 0.5s ease";
          moved++;
          scroller.style.top = top + step + 'px';

        } else {
          //重置top,moved,清除定时器
          clearInterval(timer);
          moved = 0;
          scroller.style.transition = "none";
          scroller.style.top = '0px';
          //更新数据
          this.tbody = this.tbody.slice(10).concat(this.freshData);
          timer = setInterval(task,1000);
        }
      };
    timer = setInterval(task, 1000);
  }
}

scroll-table.component.scss

.table-container {
    width: 100%;
    height: 100%;
}
.head-show {
    border-top: 1px solid #4076b9;
    height: 11.7%;
}
.scroller-container {
    border-bottom: 1px solid #4076b9;
    //border: 1px solid #fff;
    width: 100%;
    //height: 88.3%;
    height: 250px;
    box-sizing: border-box;
    overflow: hidden;
    position:relative;
    .scroller {
        position: absolute;
        top:0;
        left:0;
        transition: top .5s ease;
    }
}
table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
    //border-bottom:1px solid #4076b9;
    th {
        
        border-bottom:1px dashed #2d4f85;
        color:#10adda;
        padding:8px 2px;
        font-size: 14px;
    }
    td {
        border-bottom: 1px dashed #2d4f85;
        font-size: 12px;
        
        color:#10adda;
        position: relative;
        height: 49px;
        p{
            padding:0 2px;
            box-sizing: border-box;
            text-align:center;
            display: table-cell;
            overflow: hidden;
            vertical-align: middle;
        }
        //border-width:1px 0 ;
    }
}

Dies hat zur Folge, dass die Komponente nur einen Parameter übergeben mussurl und dann werden alle Vorgänge, einschließlich der Aktualisierung von Daten, von der Komponente selbst abgeschlossen. Dies vervollständigt die Komponentenkapselung und erleichtert die Wiederverwendung.

Zusammenfassung und Gedanken

1. Aktualisierungsdaten sollten an der Quelle aktualisiert werden, das heißt, es dürfen keine DOM-Elemente hinzugefügt oder gelöscht werden. Dieser Vorgang ist mühsam und die Leistung ist gering. Wenn man es an der Quelle platziert, muss man sich um das Array kümmern, das die Anzeigedaten in der Komponentenklasse speichert.
2. Im Hintergrund angeforderte neue Daten sollten im Voraus vorbereitet und in einem anderen temporären Array abgelegt werden. Es entspricht einem Cache und einem temporären Register.
3. Ich stelle mir die Komponente als Funktion vor. Sie hat nur einen Parameter, nämlich die Adresse der Daten. Solange dieser Parameter vorhanden ist, kann die Komponente normal funktionieren und ist von keinem anderen Wert abhängig. Lose Kupplung.
4. Stärken Sie die Idee der funktionalen Programmierung. Obwohl dies das Merkmal von React ist, bin ich immer der Meinung, dass angular auch verwendet werden kann.

Verwandte Empfehlungen:

So legen Sie benutzerdefinierte AngularJs-Anweisungen und die Namenskonvention für benutzerdefinierte Anweisungen fest

In AngularJs Was ist die Beziehung zwischen Modell, Controller und Ansicht? (Bilder und Text)

Das obige ist der detaillierte Inhalt vonAnalyse der Kapselung der Bildlauflistenkomponente in Angular 6. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn