如何动态设置已经在使用 *ngFor 的 html 的内容

How to set content of html dynamically which is already using *ngFor

我创建了 html 组件,它使用 *ngFor 动态创建 html 元素。
在 运行 上创建了总共 3 个 <p></p> 标签。 <br> 我在组件文件中提供了动态填充的主题等数据,但标记 属性 是从服务器请求的,我无法在 html 中设置它。

HTML

<div class="home_social">
  <p *ngFor="let item of homeItems"> Subject: {{item.subject}}" Marks:{{item.marks}}"</p>
</div>

组件

homeItems = [
    {subject: 'Maths', marks: this.home.maths},
    {subject: 'Science', marks: this.home.science'},
    {subject: 'English', marks: this.home.english}
  ];

  showHomeResource() {
    this.appService.getHomeResource().subscribe((data: Home) => this.home = data);
  }

  ngOnInit(): void {
    this.showHomeResource();
  }

以这种方式更新标记会出错,因为 this.home.maths 在初始化之前被调用。请求服务器后,Home 对象在 showHomeResource() 中初始化。

我们可以尝试更新组件文件中的标记而不出现此错误,或者我们可以尝试直接访问 html 文件中的 home 对象。

有什么建议吗?

所以,如果我理解错误,我们就有问题了:

 homeItems = [
    {subject: 'Maths', marks: this.home.maths},//here this.home.math is asynchronous
    {subject: 'Science', marks: this.home.science'},
    {subject: 'English', marks: this.home.english}
  ];

在 angular 中,您可以使用 observables 和 rxjs 管理这个异步数据流。显然,这不是让事情正常进行的唯一方法,但对我来说更舒服。所以我假设你有这样的组件

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit{ 
  homeItems = [
      {subject: 'Maths', marks: this.home.maths},
      {subject: 'Science', marks: this.home.science},
      {subject: 'English', marks: this.home.english}
  ];
  home: any;
  
  constructor(
    
  ) {

  }

  ngOnInit() {
    this.appService.getHomeResource().subscribe((data: Home) => this.home = data);
  }

  showHomeResource() {
    this.appService.getHomeResource().subscribe((data: Home) => this.home = 
    data);
  } 
}

你的问题是当你初始化 homeItems 时,你试图访问 home,但是 home 是未定义的 moment.a 使用 rxjs 做到这一点的方法是:

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit{ 
  
  homeItems$ = new Observable(); //we can transform homeItems$ in an observable, the $ is a convention
  home: any;
  
  constructor(
    
  ) {

  }

  ngOnInit() {
    this.homeItems$ = this.appService.getHomeResource().pipe(
      map((data: Home) => { //tha map method is like the array.map of js, but are you mapping your data!
        this.home = data 
        return  [
          {subject: 'Maths', marks: this.home.maths },      //here we can assign to the homeItems$  marks our value. the trick is that in this moment we are not rendering the view, check the html file to understand
          {subject: 'Science',  marks: this.home.science},
          {subject: 'English',  marks: this.home.english}
      ];
      })
  }

}

如果您看到我们没有在控制器中订阅。因为我们可以在 html 文件中以清晰的方式进行。

<ng-container *ngIf="homeItems$ | async; let homeItems"> <!-- here we subscribing the observable and we assign the value in homeItems -->
  <div class="home_social">
    <p *ngFor="let item of homeItems"> Subject: {{item.subject}}" Marks:{{item.marks}}"</p> <!-- here we are sure that we have data -->
  </div>
</ng-container>