我有
列表中有一个“maxHeight”,我需要检查内容何时高于“滚动高度”,显示一个按钮来读取更多内容,否则就隐藏它。
我让它工作了,但我有一个问题,当我增加这么多的学生,高度超过‘many’,他显示的按钮,这是完美的,但是,当我删除更多的学生,直到它应该再次隐藏按钮,然后错误将被触发。
SetTimeout不是我的解决方案,只是没有其他的解决方案。
<div class="input-row">
<input #studentsInput
(keypress)="onKeyPressStudent($event, studentsInput)"
class="input-field"
placeholder="Student Email or IAM"
required
type="text">
</div>
<ul #listStudents
[ngClass]="{ 'scrollable': studentsScroll }"
class="list-row">
<li *ngFor="let student of students; index as i"
class="list-item">
{{ student }}
<span (click)="deleteStudent(i)"
class="material-icons">
close
</span>
</li>
</ul>
<div *ngIf="listStudents.offsetHeight < listStudents.scrollHeight"
class="more">
<span class="material-icons">
more_horiz
</span>
</div>export class Component implements OnInit {
public students: string[] = [];
public studentsScroll = false;
public ngOnInit(): void {
}
public onKeyPressStudent(
event: KeyboardEvent,
studentsInput: HTMLInputElement,
): void {
if (event.key === 'Enter') {
if (studentsInput.checkValidity()) {
this.students.push(studentsInput.value);
studentsInput.value = '';
} else {
this.toastrService.error('Please enter a valid Email Address!');
}
}
}
public deleteStudent(index: number): void {
this.students.splice(index, 1);
}
public toggleStudentScroll(): void {
this.studentsScroll = !this.studentsScroll;
}
}发布于 2020-09-22 16:41:49
当您使用deleteStudent()时,学生数组会发生变异(剪接),列表项(li)的数量也会由于所使用的*ngFor指令而改变。这将导致绑定到*ngIf指令的listStudents元素属性更改(offsetHeight,scrollHeight)。
因此,表达式"listStudents.offsetHeight < listStudents.scrollHeight“在更改检测(由学生数组突变触发)通过模板后发生变化。
要解决这个问题,您需要确保检查(显示/隐藏按钮)发生在初始CD之外(这就是为什么setTimeout在创建自己的CD时工作)。
您可以通过使用afterContentChecked lifeCycle钩子:https://angular.io/api/core/AfterContentChecked来实现这一点。
并通过评估该钩子中的语句来评估"showmore“是否应该在DOM (true)中(false):
<div class="input-row">
<input #studentsInput
(keypress)="onKeyPressStudent($event, studentsInput)"
class="input-field"
placeholder="Student Email or IAM"
required
type="text">
</div>
<ul #listStudents
[ngClass]="{ 'scrollable': studentsScroll }"
class="list-row">
<li *ngFor="let student of students; index as i"
class="list-item">
{{ student }}
<span (click)="deleteStudent(i)"
class="material-icons">
close
</span>
</li>
</ul>
<div *ngIf="showmore" class="more">
<span class="material-icons">
more_horiz
</span>
</div>在ts中:
import { Component, ViewChild, ElementRef } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
@ViewChild('listStudents', { static: true }) listStudents: ElementRef;
private listStudentsNativeElement: HTMLElement;
public showmore: boolean = false;
public students: string[] = [];
public studentsScroll = false;
public ngOnInit(): void {
}
public onKeyPressStudent(
event: KeyboardEvent,
studentsInput: HTMLInputElement,
): void {
if (event.key === 'Enter') {
if (studentsInput.checkValidity()) {
this.students.push(studentsInput.value);
studentsInput.value = '';
} else {
console.log('Please enter a valid Email Address!');
}
}
}
public deleteStudent(index: number): void {
this.students.splice(index, 1);
}
public toggleStudentScroll(): void {
this.studentsScroll = !this.studentsScroll;
}
ngAfterViewInit() {
this.listStudentsNativeElement = this.listStudents.nativeElement;
}
ngAfterContentChecked() {
if (this.listStudentsNativeElement) {
this.showmore = (this.listStudentsNativeElement.offsetHeight < this.listStudentsNativeElement.scrollHeight);
}
}
}很少有人注意到:
相反,我使用setTimeout或RequestAnimationFrame API:
import { Component, ViewChild, ElementRef } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
@ViewChild('listStudents', { static: true }) listStudents: ElementRef;
private listStudentsNativeElement: HTMLElement;
public showmore: boolean = false;
public students: string[] = [];
public studentsScroll = false;
public ngOnInit(): void {
}
public onKeyPressStudent(
event: KeyboardEvent,
studentsInput: HTMLInputElement,
): void {
if (event.key === 'Enter') {
if (studentsInput.checkValidity()) {
this.students.push(studentsInput.value);
studentsInput.value = '';
this.checkForShowMore();
} else {
console.log('Please enter a valid Email Address!');
}
}
}
public deleteStudent(index: number): void {
this.students.splice(index, 1);
this.checkForShowMore();
}
public toggleStudentScroll(): void {
this.studentsScroll = !this.studentsScroll;
}
checkForShowMore() {
requestAnimationFrame(()=>{
this.showmore = (this.listStudentsNativeElement.offsetHeight < this.listStudentsNativeElement.scrollHeight);
})
}
ngAfterViewInit() {
this.listStudentsNativeElement = this.listStudents.nativeElement;
}
}https://stackoverflow.com/questions/64009412
复制相似问题