我在Angular工作了几年,遇到了一些奇怪的事情。我不确定这是否是该版本的怪异的Angular问题,或者我只是从未遇到过此特定问题。为了我自己的理智,我还在新的Angular应用程序中尝试了此操作,问题似乎仍然存在。
基本上,我创建了一个吸气剂来返回对象的硬编码数组。然后,我遍历模板中的对象以显示其数据并为每个项目创建一个按钮。现在,当我不使用 MatButtonModule mat-button
时,该按钮将按预期工作。但是,当我使用mat-button
时,按钮将不再触发。
在某些情况下,我可以让mat-button
工作。如果我不使用吸气剂,而是在模板中调用locationsTest
,则按钮将起作用。如果我返回变量locationsTest
,getter也将起作用。另外,如果我从吸气剂中返回一个字符串数组或一个整数数组,则mat-button
将起作用,并且单击时按钮将触发。似乎只有当吸气剂返回硬编码的对象数组时,这种情况才会发生。
所以我的问题是,有人知道为什么会这样吗?以下是失败的用例,我不确定为什么会发生这种情况。在进行以下测试时,请确保在安装@ angular / material软件包后导入 MatButtonModule ,否则mat-button
不会执行任何操作。
component.html
<div *ngFor="let location of locations">
<div>
<h4>{{ location.name }}</h4>
<p>{{ location.address }}</p>
<p>{{ location.city }} </p>
</div>
</div>
<button mat-button (click)="GoToLocation()">
Go To Location
</button>
component.ts
let locationsTest = [
{
name: "Walmart",
address: "123 Mcdougal Street W",
city: "Toronto"
},
{
name: "Barber Shop",
address: "22 cat Street",
city: "Toronto"
}
];
public get locations(): any {
return [
{
name: "Walmart",
address: "123 Mcdougal Street W",
city: "Toronto"
},
{
name: "Barber Shop",
address: "22 cat Street",
city: "Toronto"
}
];
}
public GoToLocation(): void {
console.log('Going to Location');
}
感谢您的见解。
答案 0 :(得分:0)
此问题可能是由多种不同原因引起的。我建议尝试以下内容作为检查清单,因为这些总是最终成为我的原因:
是否安装了角材料?
我发现有时我们忘记安装Angular材质,并且由于尚未发现的其他错误而将错误隐藏了。
是否导入了模块?在这种情况下,MatbuttonModule
这是我遇到的另一个常见问题,我们忘记了导入模块,因此Angular不知道组件或指令是什么。在这种情况下,Angular可能不知道mat-button
指令是什么,但是由于存在另一个错误,该错误是静默的。
(最常见),您使用的是一种吸气剂,其返回的值会自动更新!
这是我最常遇到的问题,但无法解决。当我们开发返回模拟数据时,这是很常见的。但是,如果要在getter中创建Observable或BehaviorSubject或设置一个一般值,则可能导致Angular继续触发生命周期方法。依次,这将阻止触发角度功能,因为Angular忙于不断更新。
示例:
//TS File:
public get userNames(): Observable<Array<string>> {
public names = new BehaviorSubject<Array<any>>(null);
let mockNames = [
'L1ghtk3ira',
'Thor4Life',
'OverwatchKing'
];
names.next(mockNames)
return names.asObservable();
}
/html file
<ng-container *ngIf="userNames | async as listOfUserNames;'>
<p *ngFor="let userName of listOfUserNames">
{{ userName }}
</p>
</ng-container>
上面的代码似乎无害,但是当我们在模板中使用它时,实际上是在发生什么。当我们的*ngIf
(或者即使我们直接进行*ngFor
循环异步)时,角度会获取数据并在此期间设置新数据。 Angular会检测到此情况,并决定在当前更改检测完成后执行另一次更改检测。当下一次更改检测发生时,此问题会重复出现。因此,即使您在屏幕上看不到任何变化,因为数据相同,它仍会形成不断变化的变化检测循环。因此,由于Angular会不断检查和更新自身,因此诸如(click)
事件之类的for循环中的任何内容都无法触发。
有两种方法可以解决此问题。拳头很简单,我们可以以任何方式在getter外部设置值,在我的示例中,我选择将其设置为初始值。将过去的TS文件更改为以下内容:
public names = new BehaviorSubject<Array<any>>(
[
'L1ghtk3ira',
'Thor4Life',
'OverwatchKing'
]
);
public get userNames(): Observable<Array<string>> {
return names.asObservable();
}
使用Angular时要记住的一个好的经验法则是,如果您在模板中使用吸气剂,请不要在吸气剂内设置值,因为它将触发无尽的变化检测之海。尽管应该不言而喻,但还是会发生错误。