innerHTML 属性绑定在没有页面重新加载 Angular 的情况下不会更新

问题描述 投票:0回答:1

我有一个文件上传表单和一个带有innerHTML 属性绑定的空div。当用户上传文件(excel)时,该文件将被服务器处理,转换为html并存储在数据库中。然后,Angular 将从数据库中获取数据,对其进行清理(因此 css 样式不会被删除)并通过 innerHTML 属性绑定将其插入到空 div 中。

问题是,文件上传后,如果不重新加载页面,它不会更新 div 的内容。我想更新

<div *ngIf="budgetHTML" [(innerHTML)]="budgetHTML"></div>
而不重新加载页面。

我是角度新手,关于如何实现这一目标有什么建议吗?

组件.html

<div *ngIf="budgetHTML" [(innerHTML)]="budgetHTML">
</div>

component.ts(我只包含相关代码)

export class ProgramProjectInformationComponent implements OnInit, OnDestroy {

  budgetHTML: SafeHtml;

  constructor(
    private store: Store<AppStateInterface>,
    private formBuilder: UntypedFormBuilder,
    private grantProposalService: GrantProposalService,
    private route: ActivatedRoute,
    private sanitizer: DomSanitizer,
  ) {}

  ngOnInit(): void {
    this.initializeForm();
    this.initializedValues();
    this.initializePdoPrograms();
    this.initializePdoBankAccounts();
    this.intializeListeners();
    this.initializeBudgetTable();
  }

  initializedValues() {
    this.grantProposalData$ = this.store.pipe(select(grantProposalSelector));
    this.isLoading$ = this.store.pipe(select(isFetchingGrantProposalSelector));
    this.composeBankAccount$ = this.store.pipe(select(grantProposalComposeBankAccountSelector));
    this.grantProposalDraftStatus$ = this.store.select(grantProposalDraftStatusSelector);
  }

    initializeBudgetTable() {
        this.grantProposalData$
        .pipe(
            takeUntil(this.destroy$)
        )
        .subscribe(data => {
      this.budgetHTML = this.sanitizer.bypassSecurityTrustHtml(data?.budget_info);
    });     
    }

  /**
   * for saving/passing the Donors data to api
   *
   * @return void
   */
  importBudget() {
    this.loadingUpload = true;
    
    if (this.budgetForm.valid) {      
      // convert formControl to FormData to allow sending images/files
      let formData = this.convertToFormData();      
      
      this.grantProposalId$.pipe(takeUntil(this.destroy$)).subscribe(id => {
        formData.set('grant_proposal_id', id);
      });
      
      this.grantProposalService
        .importBudgetTable(formData)
        .pipe(
          takeUntil(this.destroy$)
        )
        .subscribe({
          next: (res) => {
            this.showAlertDataSaved(res.results.message);
            this.initializedValues();
            this.initializeBudgetTable();
          },
          error: (err) => {
            this.showAlertSavingFailed(err.error.message);
            this.loadingUpload = false;
          },
          complete: () => {
            this.loadingUpload = false;
          }
        })
    } else {
      this.loadingUpload = false;
      this.showAlertCheckFields('Please fill in the required fields to proceed.');
    }
  }
}

javascript angular innerhtml
1个回答
0
投票
  1. 确保此流
    this.grantProposalData$ = this.store.pipe(select(grantProposalSelector));
    在收到 API 响应后发出新值。
  2. 等待
    grant_proposal_id
    设置后再发送
    formData
  3. 您不需要每次调用
    takeUntil(this.destroy$)
    时都需要
    importBudget
    ,您可以使用
    first
    来代替。

所以尝试以下方法:

importBudget() {
  this.loadingUpload = true;

  if (this.budgetForm.valid) {
    // convert formControl to FormData to allow sending images/files
    const formData = this.convertToFormData();

    this.grantProposalId$
      .pipe(
        first(),
        switchMap(id => {
          formData.set('grant_proposal_id', id);

          return this.grantProposalService.importBudgetTable(formData).pipe(first());
        }),
      )
      .subscribe({
        next: res => {
          this.showAlertDataSaved(res.results.message);
          // Remove these 2 lines and make sure you assign a new value for grantProposalSelector
          // this.initializedValues();
          // this.initializeBudgetTable();
        },
        error: err => {
          this.showAlertSavingFailed(err.error.message);
          this.loadingUpload = false;
        },
        complete: () => {
          this.loadingUpload = false;
        },
      });
  } else {
    this.loadingUpload = false;
    this.showAlertCheckFields('Please fill in the required fields to proceed.');
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.