如何在模型对话框中显示不同的输入数据?

How to show different input data in model dialog?

我制作了一个带有输入字段的模板表单。我想在模式对话框中显示其中一些输入字段数据。我能够向模态对话框发送一个值,但我正在考虑使用一个可重用的模态组件。

HTML代码:

<div class="d-flex">
    <div style="width: 10rem">
      <app-editable-input [text]="foodModel.standardName" (onUpdate)="foodModel.standardName = $event"></app-editable-input>
    </div>
    <mat-icon style="margin-left: 0.5rem; margin-top: 0.6rem; font-size: 2rem;cursor: pointer;" (click)="openDialog()">language</mat-icon>
  </div>
<table class="table-details w-100">
  <tr>
    <th>ID</th>
    <th>Name</th>
    <th>Carbohydrates</th>
    <th>Fats</th>
    <th>Protein</th>
    <th>Calories</th>
    <th>Lang</th>
    <th>Status</th>
    <th>Action</th>
  </tr>
  <tr *ngFor="let food of foodModel.servings; let i = index"> <!-- 'as' assigned serving. Donot use 'as'. -->
    <td>{{ food.id }}</td>
    <td>
      <div>
        <app-editable-input [text]="food.localisedName | head" (onUpdate)="food.localisedName= $event"></app-editable-input>
      </div>
    </td>
    <td>
      <app-editable-input [text]="food.carbs" [unit]="'gms'"></app-editable-input>
    </td>
    <td>
      <app-editable-input [text]="food.fats" [unit]="'gms'"></app-editable-input>
    </td>
    <td>
      <app-editable-input [text]="food.protein" [unit]="'gms'"></app-editable-input>
    </td>
    <td>
      <div style="margin-left: 1rem;">{{ food.calories }} kcals</div>
    </td>
    <td>
      <mat-icon style="margin-left: 0.6rem;" (click)="openDialog()">language</mat-icon>
    </td>
    <td>
      <div class="boolean">
        <mat-icon>lens</mat-icon>
        Active
      </div>
    </td>
    <td>
      <mat-icon style="margin-left: 0.5rem;" (click)="onClickDelete(i)">delete</mat-icon>
    </td>
  </tr>
</table>

在上面你可以看到 (click)="openDialog()" 被调用了两次。我希望在单击时将两个单击事件的值显示在同一个模式对话框中。不是同时,而是一个代替另一个。

TS代码:

import { Component, Inject, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Router } from '@angular/router';
import { ModalAllComponent } from '../modal/modal-all/modal-all.component';

export interface FoodModel {
  standardName: string;
  localisedName: {
    code: string;
    title: string;
    value: string;
  }[];
  ratingInfo?: {
    rating: number;
    title: string;
  };
  servings: Serving[];
};

interface Serving {
  id?: number;
  standardName: string;
  localisedName: {
    lang: string;
    value: string;
  }[];
  carbs: number;
  protein: number;
  fats: number;
  calories:number;
  langs: string;
}

@Component({
  selector: 'app-food-details',
  templateUrl: './food-details.component.html',
  styleUrls: ['./food-details.component.scss']
})
export class FoodDetailsComponent implements OnInit {
  name!:any

  foodModel: FoodModel = {
    standardName: '',
    localisedName: [],
    servings: []
  };

  constructor(private router: Router, private dialog:MatDialog) { }

  ngOnInit(): void {

  }

  onClickAddServing(): void {
    const serving: Serving = {
      standardName: '',
      localisedName: [
        {
          lang: 'en',
          value: ''
        }
      ],
      carbs: 0,
      protein: 0,
      fats: 0,
      calories:0,
      langs: 'en, fr, fr-CA'
    };
    this.foodModel.servings.push(serving);

    //const val = serving.localisedName.map(i => i.value)
  }

  onClickDelete(index: number) {
    this.foodModel.servings.splice(index, 1);
  }

  back() {
    this.router.navigate(['food-content']);
  }

  openDialog(){
  /*   let data = {
      msg:"message from food-details"
    } */
    const dialogRef = this.dialog.open(ModalAllComponent, {
      width: '14.5rem',
      data:{ name: this.foodModel.standardName}
    })
  }
}    

这是 app-editable-input HTML:

<div class="edit-container">
  <p class="edit-input d-flex align-items-center pl-1 pr-1 w-100" [ngStyle]="{'font-size': textSize ?? '2rem'}" *ngIf="!edit" (click)="edit = true">
    <span style="min-width: 6rem;height: 3rem; padding: 0.8rem;" class="flex-grow-1">{{ text }}{{ unit }}</span>
    <span class="ml-2"><mat-icon>edit</mat-icon></span>
  </p>
  <div *ngIf="edit">
    <input class="form-control" [(ngModel)]="editedText" (blur)="onInputBlur();edit = false;" />
  </div>
</div>

这是 app-editable-input ts:

  @Input() text: string | number = '';
  @Input() textSize: string = '1rem';
  editedText: string | number = '';
  @Input() unit:string = '';
  @Output() onUpdate: EventEmitter<any> = new EventEmitter();

  edit: boolean = false;

  constructor() { }

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

  ngOnChanges(): void {
    this.setDefaults();
  }

  setDefaults() {
    this.editedText = this.text;
  }

  onInputBlur() {
    this.onUpdate.emit(this.editedText);
    this.text = this.editedText;
  }

提前致谢!

我建议给模态组件一个输入 prop: string,您将其作为 data 的一部分传递。然后,订阅 dialogRef 的关闭事件(这也应该再次传递该道具)然后你可以做类似 this.foodModel[prop] = newVal 的事情(可能需要类型转换)。

括号表示法与点表示法类似,但使用字符串,例如this.foodModel.standardName 等价于 this.foodModel['standardName'].

编辑:
关于如何打开对话框并获得结果的更多示例(不完整且不一定正确的语法):

// open from template like (click)="openDialog('standardName')"
openDialog(propName: keyof FoodModel){  
  const dialogRef = this.dialog.open(ModalAllComponent, {
    width: '14.5rem',
    data:{ 
      prop: propName,
      value: this.foodModel[propName]
    }
  });

  dialogRef.afterClosed().subscribe((result) =>
    this.foodModel[result.prop] = result.value;
  );
}

在对话框中是这样的:

export class YourDialog {
  prop: keyof FoodModel;
  value: string | number;

  constructor(public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: {prop: string, value: string | number}) { 
    this.prop = this.data.prop;
    this.value = this.data.prop;
  }

  closeDialog() {
    this.dialogRef.close({prop: this.prop, value: this.value});
  }
}

MatDialog 的文档:https://material.angular.io/components/dialog/overview