在第一次赋值后初始值发生变化后,如何使视图反映内插变量的变化?
How to make the view reflects a change made in a interpolated variable after the initial value has been changed after the first assignment?
在应用程序中工作时,我必须将值设置为一个变量(这将获得三个不同的可能值之一),具体取决于选中的单选按钮(用户可以选择 3 个单选按钮 select).我将此值设置为对象数组的某些 属性,该对象数组仅在用户 select 按下单选按钮后才会显示。但是变量在视图中从未改变。所以我用一个简单的例子简化了这个案例,但我没有运气,我不知道为什么它不更新视图,即使变量已经被分配了新值。
请看一下这个简单的例子:
这是一个app.component.html
<ng-container *ngFor="let item of items">
<p>{{item.name}}</p>
</ng-container>
这是它的 .ts 文件:
export class AppComponent implements OnInit {
public firstValue: string = "Gatsu";
constructor(private cd: ChangeDetectorRef, private nz: NgZone) {}
ngOnInit() {
this.init();
}
public items = [{ name: this.firstValue }, { name: "Kenshin" }];
init(){
this.firstValue = "Itachi";
// this.cd.detectChanges();
// this.cd.markForCheck()
// this.nz.run(()=>this.firstValue = 'Itachi')
alert(this.firstValue); // ---> this alerts 'Itachi'
}
}
我尝试应用 changeDetectorRef
和 ngZone
看看我是否有运气,但是,即使在 alert
消息上有 'Itachi',视图继续呈现初始值 'Gatsu'.
最后我把this.firstValue = "Itachi";
换成this.items[0].name = "Itachi"
解决了,但我一直不知道为什么第一次尝试没有成功。
好心的小伙伴们能不能让我明白第一次尝试的失败在哪里,实现我想要做的事情的最佳方法是什么?
谢谢。
您找到的解决方案是正确的。
发生这种情况是因为 firstName 的基础类型是一个字符串,它是一个值(原始)类型。因此,当您将其分配给数组中第一个点的名称 属性 时,它会复制值(而不是引用)。这意味着对 firstName 的进一步更改不会影响数组点。
这里有一篇关于 mdn 的好文章,其中详细介绍了这些不同的底层类型:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures
您遇到的问题与 Angular 无关,因为当您将变量“firstValue”设置为任何其他值时,框架不会收到任何更改通知。发生这种情况是因为您没有更改数组 [0].name 值,因为这样做时
public items = [{ name: this.firstValue }, { name: "Kenshin" }];
您没有保留对变量的引用,您只是将索引 0 处对象的键设置为变量第一个值“Gatsu”。
事实上,如果你把 console.log() 放在这里:
init(){
this.firstValue = "Itachi";
console.log(this.items); // <---- console.log here
// this.cd.detectChanges();
// this.cd.markForCheck()
// this.nz.run(()=>this.firstValue = 'Itachi')
alert(this.firstValue); // ---> this alerts 'Itachi'
}
您会注意到数组的值仍然相同。
如果您真的想更改索引 0 处对象的键“名称”,您应该像这样更改值:
this.items[0].name = "Itachi";
或者您可以只使用参考:
this.items.find(item => item.name == "Gatsu").name = "Itachi";
希望这能解决您的问题。
在应用程序中工作时,我必须将值设置为一个变量(这将获得三个不同的可能值之一),具体取决于选中的单选按钮(用户可以选择 3 个单选按钮 select).我将此值设置为对象数组的某些 属性,该对象数组仅在用户 select 按下单选按钮后才会显示。但是变量在视图中从未改变。所以我用一个简单的例子简化了这个案例,但我没有运气,我不知道为什么它不更新视图,即使变量已经被分配了新值。
请看一下这个简单的例子:
这是一个app.component.html
<ng-container *ngFor="let item of items">
<p>{{item.name}}</p>
</ng-container>
这是它的 .ts 文件:
export class AppComponent implements OnInit {
public firstValue: string = "Gatsu";
constructor(private cd: ChangeDetectorRef, private nz: NgZone) {}
ngOnInit() {
this.init();
}
public items = [{ name: this.firstValue }, { name: "Kenshin" }];
init(){
this.firstValue = "Itachi";
// this.cd.detectChanges();
// this.cd.markForCheck()
// this.nz.run(()=>this.firstValue = 'Itachi')
alert(this.firstValue); // ---> this alerts 'Itachi'
}
}
我尝试应用 changeDetectorRef
和 ngZone
看看我是否有运气,但是,即使在 alert
消息上有 'Itachi',视图继续呈现初始值 'Gatsu'.
最后我把this.firstValue = "Itachi";
换成this.items[0].name = "Itachi"
解决了,但我一直不知道为什么第一次尝试没有成功。
好心的小伙伴们能不能让我明白第一次尝试的失败在哪里,实现我想要做的事情的最佳方法是什么?
谢谢。
您找到的解决方案是正确的。
发生这种情况是因为 firstName 的基础类型是一个字符串,它是一个值(原始)类型。因此,当您将其分配给数组中第一个点的名称 属性 时,它会复制值(而不是引用)。这意味着对 firstName 的进一步更改不会影响数组点。
这里有一篇关于 mdn 的好文章,其中详细介绍了这些不同的底层类型: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures
您遇到的问题与 Angular 无关,因为当您将变量“firstValue”设置为任何其他值时,框架不会收到任何更改通知。发生这种情况是因为您没有更改数组 [0].name 值,因为这样做时
public items = [{ name: this.firstValue }, { name: "Kenshin" }];
您没有保留对变量的引用,您只是将索引 0 处对象的键设置为变量第一个值“Gatsu”。 事实上,如果你把 console.log() 放在这里:
init(){
this.firstValue = "Itachi";
console.log(this.items); // <---- console.log here
// this.cd.detectChanges();
// this.cd.markForCheck()
// this.nz.run(()=>this.firstValue = 'Itachi')
alert(this.firstValue); // ---> this alerts 'Itachi'
}
您会注意到数组的值仍然相同。 如果您真的想更改索引 0 处对象的键“名称”,您应该像这样更改值:
this.items[0].name = "Itachi";
或者您可以只使用参考:
this.items.find(item => item.name == "Gatsu").name = "Itachi";
希望这能解决您的问题。