【问题标题】:Angular 10 - How to auto load new items when collection changesAngular 10 - 如何在集合更改时自动加载新项目
【发布时间】:2021-03-03 11:42:59
【问题描述】:

这个想法是,当用户滚动到页面底部时,它应该添加更多项目。 我在 onScroll() 方法的 posts 变量中添加了更多项目,但我无法弄清楚 html 模板将如何自动加载新项目。

home-component.component.ts

import { Component, OnInit } from '@angular/core';
import { Post } from '../post';

@Component({
  selector: 'home-component',
  templateUrl: './home-component.component.html',
  styleUrls: ['./home-component.component.css']
})
export class HomeComponentComponent implements OnInit {
  numbers(n: number): number[] {
    return [...Array(n).keys()];
  }
  page: number = 1;
  posts: Post[] = [];

  constructor() {
    for (let i = 1; i <= 30; i++) {
      let imgNo = ((2 * i) % 3) + 1;
      let p = new Post;
      p.userName = "username" + i;
      p.profileIconURL = "../assets/images/dp.png";
      p.postImageURL = "../assets/images/post" + imgNo + ".png";
      p.postMessage = "message for the post " + i + "...";
      p.noOfLikes = 2 * i;
      this.posts.push(p);
    }
  }

  ngOnInit(): void {
  }

  onScroll() {
    //this.page++;
    for (let i = 1; i <= 3; i++) {
      let imgNo = ((2 * i) % 3) + 1;
      let p = new Post;
      p.userName = "username" + i;
      p.profileIconURL = "../assets/images/dp.png";
      p.postImageURL = "../assets/images/post" + imgNo + ".png";
      p.postMessage = "message for the post " + i + "...";
      p.noOfLikes = 2 * i;
      this.posts.push(p);
    }
  }
}

home-component.component.html

<span *ngFor="let post of posts">
  <post-component [userName]="post.userName"
                  [profileIconURL]="post.profileIconURL"
                  [postImageURL]="post.postImageURL"
                  [postMessage]="post.postMessage"
                  [noOfLikes]="post.noOfLikes"
  >
  </post-component>
</span>

【问题讨论】:

  • 您可以使用 rxjs observables 和 Angular 异步管道的强大功能

标签: angular


【解决方案1】:

您可以使用 rxjs 可观察对象,也可以使用更改检测策略让 HTML 知道数据已更改。

import {ChangeDetectorRef} from @angular/core
...

constructor (private cdRef: ChangeDetectorRef) {}
..

onListLoad() {
... Loading algorithm
this.cdRef.detectChanges()
}

这就是你可以使用它的方式。 Change Detector 会通知 HTML 页面它必须重新加载自己。

您还可以阅读有关 Angular 中虚拟滚动的更多信息,它可以更优雅地处理它,并且始终管理 DOM 上的负载。这是一个article,可以帮助您。

【讨论】:

  • 我开始工作了。我会尽快发布我的答案。但我会检查文章以了解想法。谢谢。
【解决方案2】:

我让它工作了。这个post 帮助了。

home-component.component.ts

import { Component, OnInit } from '@angular/core';
import { Post } from '../post';
import { Observable, BehaviorSubject, of } from 'rxjs';
import { take } from 'rxjs/operators';
import { HostListener } from '@angular/core';

@Component({
  selector: 'app-home-component',
  templateUrl: './home-component.component.html',
  styleUrls: ['./home-component.component.css']
})
export class HomeComponentComponent implements OnInit {
  numbers(n: number): number[] {
    return [...Array(n).keys()];
  }
  page: number = 1;
  posts: Post[] = [];
  subject: BehaviorSubject<any[]> = new BehaviorSubject<any>([]);
  array$: Observable<any> =  this.subject.asObservable();

  constructor() {
    for (let i = 1; i <= 5; i++) {
      let imgNo = ((2 * i) % 3) + 1;
      let p = new Post;
      p.userName = "username" + i;
      p.profileIconURL = "../assets/images/dp.png";
      p.postImageURL = "../assets/images/post" + imgNo + ".png";
      p.postMessage = "message for the post " + i + "...";
      p.noOfLikes = 2 * i;
      //this.posts.push(p);
      this.addElementToObservableArray(p);
      console.log(i);
    }
  }

@HostListener('window:scroll', ['$event']) onScrollEvent(event: any){
  //https://stackoverflow.com/questions/41304968/how-to-get-on-scroll-events

  let pos = (document.documentElement.scrollTop || document.body.scrollTop) + document.documentElement.offsetHeight;
  let scrolltop = (document.documentElement.scrollTop || document.body.scrollTop);
  let max = document.documentElement.scrollHeight;
  let windowheight = window.innerHeight;
  let isbottom = scrolltop + windowheight == max;
  let istop = scrolltop == 0;
  console.log(pos + "," + max + "," + document.documentElement.offsetHeight + "," + scrolltop);

   if(isbottom )   {
      //console.log("End");
      this.page++;
      console.log(this.page);
      for (let i = this.page; i < this.page+5; i++) {
        let imgNo = ((2 * i) % 3) + 1;
        let p = new Post;
        p.userName = "username" + i;
        p.profileIconURL = "../assets/images/dp.png";
        p.postImageURL = "../assets/images/post" + imgNo + ".png";
        p.postMessage = "message for post " + i + "...";
        p.noOfLikes = 2 * i;
        //this.posts.push(p);
        this.addElementToObservableArray(p);
      }
 }
}

  ngOnInit(): void {
  }

  addElementToObservableArray(item) {
    this.array$.pipe(take(1)).subscribe(val => {
      console.log(val)
      const newArr = [...val, item];
      this.subject.next(newArr);
    })
  }
}

home-component.component.html

<div *ngFor="let post of array$ | async">
  <app-post-component [userName]="post.userName"
                  [profileIconURL]="post.profileIconURL"
                  [postImageURL]="post.postImageURL"
                  [postMessage]="post.postMessage"
                  [noOfLikes]="post.noOfLikes"
  >
  </app-post-component>
</div>

post-component.component.ts

import { Component, OnInit, Input } from '@angular/core';
import { Post } from '../post'

@Component({
  selector: 'app-post-component',
  templateUrl: './post-component.component.html',
  styleUrls: ['./post-component.component.css']
})
export class PostComponentComponent implements OnInit {
  @Input() userName: string;
  @Input() profileIconURL: string;
  @Input() postImageURL: string;
  @Input() postMessage: string;
  @Input() noOfLikes;
  @Input() comments;

  @Input() post: any;

  constructor() {
    this.userName = "Test user";
    this.profileIconURL = "../assets/images/dp.png";
    this.postImageURL = "../assets/images/postdefault.png";
    this.noOfLikes = 0;
    this.postMessage = "post message...";
    this.comments = "";
  }

  ngOnInit(): void {
  }

}

post-component.component.html

<div class="container text-center py-4" style="width:480px;">
  <div class="card bg-white rounded border bg-primary">
    <div class="row">
      <div class="col-md-2 text-left ml-2"><img src="{{profileIconURL}}" width="48"></div>
      <div class="col-md-7 text-left justify-content-left d-flex align-items-center p-0">{{userName}}</div>
      <div class="col-md-2 mr-2">
        <div class="float-right">...</div>
      </div>
    </div>
    <div class="row">
      <div class="col" style="height:400px;"><img src="{{postImageURL}}" width="100%" height="100%"></div>
    </div>
    <div class="row">
      <div class="col text-left ml-2">{{noOfLikes}} Likes</div>
    </div>
    <div class="row">
      <div class="col text-left ml-2">{{postMessage}}</div>
    </div>
  </div>
</div>

post.ts

export class Post {
  id: number;
  userName: string;
  profileIconURL: string;
  postImageURL: string;
  postMessage: string;
  noOfLikes: number;

  constructor() {
    this.id = 0;
    this.userName = "Test user";
    this.profileIconURL = "../assets/images/dp.png";
    this.postImageURL = "../assets/images/postdefault.png";
    this.noOfLikes = 0;
    this.postMessage = "braydoncoyer I can't wait to see the new Star Wars movie.";
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-19
    • 1970-01-01
    • 2019-04-21
    • 1970-01-01
    • 1970-01-01
    • 2013-10-06
    • 2016-04-26
    相关资源
    最近更新 更多