【问题标题】:Angular model field not updated on subscribe订阅时未更新角度模型字段
【发布时间】:2020-02-29 09:20:55
【问题描述】:

简化我得到了一个视图:

<table class="table table-bordered table-striped">
<tr>
  <td>
    <label>First Name</label>
    <input type="text" class="form-control" [(ngModel)]="profile.FirstName">
  </td>
  <td>
    <label>Last Name</label>
    <input type="text" class="form-control" [(ngModel)]="profile.LastName">
  </td>
 </tr>
</table>

构造函数创建空白配置文件并且 ngOnInit 检查更改的组件:

profile: Profile;
sub: any;
constructor(private serv: ProfileService, private route: ActivatedRoute) {
  this.profile = new Profile('', '');
}

ngOnInit(): void {
  this.sub = this.route.params.subscribe(params => {
    const id = params['id'];
    this.serv.getProfile(id).subscribe(res => {
      console.log(res);
      this.profile = res;
      // this.profile.LastName = res.LastName; doesn't work either
    });
  });
}

在控制台上记录了正确的配置文件,但表格字段未更新。怎么了? 感谢您的帮助!

【问题讨论】:

标签: angular


【解决方案1】:

为了触发它的绑定,Angular 正在寻找的是一个参考变化。

当您这样分配时,您不会更改参考:

this.profile.LastName = res.LastName;

你想做的是像这样使用扩展运算符:

this.profile = { ...this.profile, lastName: res.lastName }

【讨论】:

    【解决方案2】:

    您的代码看起来有效,应该更新视图。所以看起来你正在使用onPush Change Detection Strategy。如果是,那么您需要显式运行更改检测:

    @Component({
      selector: 'yourSlector',
      template: `<!-- The code is omitted for the brevity -->`,
      changeDetection: ChangeDetectionStrategy.OnPush
    })
    export class CounterComponent { 
    
      constructor(private cdr: ChangeDetectorRef) {}
    
      ngOnInit(): void {
          this.sub = this.route.params.subscribe(params => {
              const id = params['id'];
              this.serv.getProfile(id).subscribe(res => {
                  console.log(res);
                  this.profile = res;
                  this.cdr.detectChanges();          
              });
          });
       }
    }
    

    请看a work stackblitz example.

    【讨论】:

    • 这适用于 {{profile.FirstName}} 构造,但不适用于 [(ngModel)]="profile.FirstName"。还缺少什么?
    • @Gerard 你能创建一个 stackblitz 示例吗?
    • 相当新手...,可以吗?切换到 ReactiveFormsModule:this.sub = this.serv.getProfile(this.id).subscribe(p => {this.editForm.setValue(p); });工作正常!动态更改输入字段可能有点奇怪(如果不是原始的)
    • 因此不需要 ChangeDetectionStrategy 更改。也适用于订阅: ngOnInit() { this.subscription = this.getAsyncData().subscribe(p => (this.person = p)); } getAsyncData() { // 伪造慢速异步数据返回 of({ name: 'Moonwalker' }).pipe(delay(2000)); }
    • @Gerard 太棒了!:)
    【解决方案3】:

    整个问题与 PascalCase 与 CamalCase 有关。订阅中的分配不会失败,而 REST 调用会将 CamelCase 中的属性与 PascalCase 中 Profile 类的属性一起传递。

    this.serv.getProfile(id).subscribe(res => {
      console.log(res);
      this.profile = res; // THIS WILL NOT FAIL
    });
    

    因此永远不会分配名字、姓氏等。

    【讨论】:

      猜你喜欢
      • 2019-01-12
      • 1970-01-01
      • 2015-02-13
      • 1970-01-01
      • 2021-05-28
      • 1970-01-01
      • 1970-01-01
      • 2022-07-01
      • 1970-01-01
      相关资源
      最近更新 更多