angular - 更改界面中的数据后的角度html更新
问题描述
我想做的是更新我的界面,它有一些用户信息,然后当它发生变化时,我希望结果反映在 HTML 输出中。
在我的 HTML 页面上,我有一个输入,允许用户添加附加评论。这一切正常,但是,用户输入实际上并未显示在页面上,但确实对我的界面进行了必要的更改。
在下面的 HTML 文件中,用户将在输入中键入一些内容。然后将保存到我的界面,这是每个学生的数据,然后将在此处可见<p>{{the students.grades}}<p>
<div class='studentCard' *ngFor='let student of students | studentSearch: StudentSearch'>
<img class='studentImg' src={{student.pic}}/>
<div class='studentInfo'>
<h1>{{student.name | uppercase}}</h1>
<div class='loca'>
<p>Email: <span>{{student.email}}</span></p>
<p>Company: <span>{{student.company}}</span></p>
<p>Skill: <span>{{student.skills}}</span></p>
<p>Average: <span>{{student.average}}</span></p>
<mat-expansion-panel [hideToggle]='true' [expanded]='true'>
<p>{{student.grades}}</p>
</mat-expansion-panel>
<p>{{student.tags}}</p>
<mat-form-field>
<input matInput (keyup.enter)='add(student.id)' placeholder="Add a tag"></mat-form-field>
</div>
</div>
<div class='expand'><span class='material-icons'>add</span></div>
</div>
此代码来自我的 component.ts 文件。现在我只是想传递一些虚拟信息来看看它是否真的有效。我可以看到它正确地更新了界面。
import { Component, OnInit } from '@angular/core';
import { Student } from '../student'
import { StudentsService } from '../students.service';
@Component({
selector: 'app-student-profiles',
templateUrl: './student-profiles.component.html',
styleUrls: ['./student-profiles.component.scss']
})
export class StudentProfilesComponent implements OnInit {
//implementing an interface to control the data and make it easy to access
students: Student[] = [];
StudentSearch=''
TagSearch=''
constructor(
private service: StudentsService
) { }
ngOnInit(): void {
this.service.getStudents().subscribe(
result=>result['students'].map(
x=>{this.students.push(
{
name:x.firstName+' '+x.lastName,
grades:x.grades,
average:this.computeAvg(x.grades),
company: x.company,
email: x.email,
pic: x.pic,
id: x.id,
skills: x.skill,
tags:[]
});
}
)
)
}
//find the average of all the scores of each student. Calculates the total, then devides by the length of scores array.
computeAvg(x){
let total=0
x.map(score=>{total=total+Number(score)})
return(total/x.length)
}
add(id){
this.students[id-1]['tags'].push(String('100'))
console.log(this.students[id-1])
}
}
这是我用于数据的接口:
name: string;
grades: number[];
average: number;
company: string;
pic: string;
email: string;
id: number;
skills: string;
tags: string[];
}
我不明白的是,如果我使用相同的代码,但我将它从“标签”更改为“电子邮件”,那么它确实会在 HTML 中显示更新。
解决方案
Angular Change Detection 通过比较模板中存在的属性的新旧值来工作。
如果您仔细观察您的界面,email 属性是一个字符串,但 tags 属性是一个数组。
当您更改电子邮件的值时,Angular 能够知道此原始类型的新旧值不同,然后更新视图。
当您向 tags 数组添加新标签时,对数组的引用不会更改它只会更改其内容,因此 Angular 不会检测到它,因此不会更新视图。
在这种情况下,一个非常简单的解决方案是在添加新标签后创建一个新数组,以便引用更改,您可以使用拼接或展开运算符来做到这一点:
array.slice()
or
[...array]
考虑到您正在制作数组的副本。
当引用未更改并且需要副本时,角度更改检测的相同行为适用于对象类型。
其他一些 Web 框架(即 React)使用不可变范式使这些事情更容易理解并避免陷阱。
有关角度变化检测的更多信息:
推荐阅读
- f# - 这些从未更改(或仅在开始时更改一次)设置的模块属性?
- jquery - 打字稿模型到json - 忽略空值属性
- excel - 在 VBA 中使用字符串变量设置变量名
- c - 为什么我的检查 BST 树是否 AVL 错误的代码?
- android - googleApiClient.Builder(this) 不存在
- amazon-web-services - AWS ECS 上的 Windows Docker 容器 - IAM 角色
- php - 将带有函数的变量传递给另一个变量并返回它
- c - struct 的标量初始化程序中的多余元素
- sql - Oracle SQL - 具有多个标头的条件聚合透视
- python-3.x - 弹出窗口出现在 Folium 中的鼠标悬停上