Angular 10 - 如何在集合更改时自动加载新项目
Posted
技术标签:
【中文标题】Angular 10 - 如何在集合更改时自动加载新项目【英文标题】:Angular 10 - How to auto load new items when collection changes 【发布时间】: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 异步管道的强大功能 【参考方案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://***.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" ></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" ></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.";
【讨论】:
以上是关于Angular 10 - 如何在集合更改时自动加载新项目的主要内容,如果未能解决你的问题,请参考以下文章