【问题标题】:Angular ngModel inside ngFor, with pipe and map, not workingngFor中的Angular ngModel,带有管道和地图,不起作用
【发布时间】:2020-08-09 04:32:50
【问题描述】:

我在这种情况下遇到了问题:

@Component({
  selector: 'my-app',
  template: `
    {{items | async| json}}

    <div *ngFor="let item of items | async">
      <input type=checkbox [(ngModel)]="item.b"/>
    </div>
  `
})
export class AppComponent  {
  items = of([{
    name: '1',
  },
  {
    name: '2',
  },
  {
    name: '3',
  }])
  .pipe(map(i=>{
    return i.map(i=>{
      return {
        i: i,
        b: false
      }
    })
  }))
}

Stackblitz app

问题是 ngModel 不工作,我看不到 b 属性的变化。 如果我删除地图管道并将布尔属性放在第一个数组中,则一切正常。 我错过了什么吗?有什么问题?

谢谢

【问题讨论】:

  • 不清楚你想在这里实现什么..?为什么是可观察的?
  • 我使用 observable 是因为这只是一个简单的例子。在我的真实应用程序中,我有一个可观察的作为来自 http 调用的响应,我需要在响应中添加一些属性(一个选定的布尔属性),然后才能显示在模板上
  • @PavanShukla,感谢您的解决方案

标签: angular rxjs angular-ngmodel


【解决方案1】:

你没有做错任何事。如果您在ngFor 中渲染{{item.b}},您将看到值在truefalse 之间正确变化。正如另一个答案中提到的,这是因为引用和更改检测。您还可以使用ngOnInitsubscribe 将可观察数据简单地保存为您的类的属性:

import { Component } from "@angular/core";
import { of } from "rxjs";
import { map } from "rxjs/operators";

@Component({
  selector: "my-app",
  template: `
    {{ items | json }}

    <form #myForm="ngForm">
      <div *ngFor="let item of items">
        <input [name]="item.i.name" type="checkbox" [(ngModel)]="item.b" />
      </div>
    </form>
  `
})
export class AppComponent {
  items: any[] = [];

  ngOnInit() {
    this.getData().subscribe(data => (this.items = data));
  }

  private getData() {
    return of([
      {
        name: "1"
      },
      {
        name: "2"
      },
      {
        name: "3"
      }
    ]).pipe(
      map(i => {
        return i.map(i => {
          return {
            i: i,
            b: false
          };
        });
      })
    );
  }
}

这里有一个example 正在运行。如果需要,不要忘记清理任何可观察对象以避免内存泄漏。

【讨论】:

  • 感谢您的所有回答。只是为了更好地理解,是否可以只维护可观察的项目?我的意思是,有没有办法触发变更检测?
  • @DavideC 有几种方法可以解决这个问题。我建议看看这个问题/答案:stackoverflow.com/questions/36919399/…
【解决方案2】:

其实你做的是对的。 要检查我的意思,请将您的代码更改为:

<input type=checkbox (change)="change(item)" [(ngModel)]="item.b"/>

change(item) {
 console.log(item);
}

这并没有反映在 dom 上,因为 items 数组被映射到相同的内存位置,并且更改其中的元素不会导致角度更改检测来触发显示更改。

【讨论】:

    猜你喜欢
    • 2019-01-06
    • 1970-01-01
    • 1970-01-01
    • 2019-12-16
    • 1970-01-01
    • 2017-06-22
    • 1970-01-01
    • 1970-01-01
    • 2018-06-03
    相关资源
    最近更新 更多