【问题标题】:How to set content of html dynamically which is already using *ngFor如何动态设置已经使用 *ngFor 的 html 内容
【发布时间】:2021-06-12 16:54:50
【问题描述】:

我创建了 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 在初始化之前被调用。请求服务器后在 showHomeResource() 中初始化 Home 对象。

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

有什么建议吗?

【问题讨论】:

  • 主题:{{item?.subject}} 标记:{{item?.marks }}

  • 是的,但这会导致错误原因标记在初始化之前调用主对象。

标签: html angular typescript httpclient


【解决方案1】:

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

 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 尚未定义。使用 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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-06
    • 2016-04-06
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 2018-03-09
    • 2012-05-18
    • 2020-10-05
    相关资源
    最近更新 更多