簡體   English   中英

如何讓我的 ngModel 在我的 ng-template 中自動工作?

[英]How can i make my ngModel to work automatically in my ng-template?

我有很多帶有標簽和輸入的表單組。我想制作可重用的 ng-template

所以我有

  <div class="form-group">
      <label class="form-control-label" for="address">Address</label>
       <input [disabled]="isTheLoggedInUserAdmin" id="address" class="form-control form- 
       control-alternative"
       [(ngModel)]="sharedService.tempUser.address" name="address" type="text">
  </div>

並使用 ng-template 將其轉換為

 <ng-template [ngTemplateOutlet]="formGroup"
      [ngTemplateOutletContext]="{data: {inputId:'address', label:'Address', ngModel: 
      sharedService.tempUser.address }}"
></ng-template>


<ng-template #formGroup let-data="data">
 <div class="form-group">
    <label class="form-control-label" [for]="data.inputId">{{data.label}}</label>
    <input [disabled]="isTheLoggedInUserAdmin" [id]="data.inputId" class="form-control form-control- 
    alternative"
    [(ngModel)]="sharedService.tempUser.address" [name]="data.inputId" type="text">
  </div>
</ng-template>

所以我在這里自動傳遞 inputId,label 名稱,現在 ngModel 是硬編碼的,它指向sharedService.tempUser.address

但是我的 ng-template 需要是動態的,因此使用 ng-template 調用我應該傳遞like label for example參數 - 參數應該指向我的 typescript 文件中的不同 ngModel 變量

但是當我這樣做時

 <div class="form-group">
    <label class="form-control-label" [for]="data.inputId">{{data.label}}</label>
    <input [disabled]="isTheLoggedInUserAdmin" [id]="data.inputId" class="form-control form-control-alternative"
      [(ngModel)]="data.ngModel" [name]="data.inputId" type="text">
  </div>

現在data.ngModel是從 ng-template 調用發送的——它是sharedService.tempUser.address ,我從sharedService.tempUser.address獲得實際值,但是*問題是 ngModel 在這里不起作用`

當我輸入內容時,它沒有更新

我該如何解決這個問題?

您可能希望編寫ControlValueAccessor的實現作為替代方案。 這是一種 Angular 官方方法來創建與表格 API 兼容的可重用組件。 一個最小的例子是這樣的:

my-custom-control.component.html

<div class="form-group">
   <label class="form-control-label" for="{{data.field}}">{{data.label}}</label>
   <input [disabled]="disabled" id="{{data.field}}" class="form-control form-control-alternative"
          [value]="value" name="{{data.field}}" type="text"
          (change)="onChange($event)" (blur)="onBlur($event)">
</div>

my-custom-control.component.ts

/**
    import things....
**/

@Component({
  selector: 'MyControl',
  templateUrl: './my-custom-control.component.html',
  styleUrls: ['./my-custom-control.component.scss'],
  providers: [{
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => MyControlComponent),
    multi: true
  }]
})
export class MyControlComponent implements OnInit, ControlValueAccessor {

  @Input() value: any;
  
  @Input() data: { 'field': string, 'label': string } =  { field: "default", label: "default" };
  
  @Input() disabled: boolean = false;
  setDisabledState(isDisabled: boolean) {
    this.disabled = isDisabled;
  }

  propagateChange = (_: any) => { };
  propagateTouch = () => { };
  registerOnChange(fn) {
    this.propagateChange = fn;
  }
  registerOnTouched(fn) {
    this.propagateTouch = fn;
  }
  
  constructor() {
  }

  ngOnInit() {
      
  }
  
  // value changed from ui
  onChange(event: any){
    this.value = event.target.value;
    // tell angular that the control value is changed
    this.propagateChange(this.value);
  }
  
  // received value from form api
  writeValue(newFormValue: any) {
    this.value = newFormValue;
  }
  
  // tell angular that this form control is touched
  onBlur(event: any) {
    this.propagateTouch();      
  }
}

之后,您可以重用此組件,例如:

<!-- With FormGroup -->
<form [formGroup]="myForm">
  <MyControl formControlName="address" [disabled]="isTheLoggedInUserAdmin" [data]="{ field: 'address', label: 'Address' }">
  <MyControl formControlName="title" [disabled]="isTheLoggedInUserAdmin" [data]="{ field: 'title', label: 'Title' }">
  <MyControl formControlName="surname" [disabled]="isTheLoggedInUserAdmin" [data]="{ field: 'surname', label: 'Surname' }">
  <!-- other controls... -->
</form>

<!-- Without FormGroup -->
<div>
  <MyControl [(ngModel)]="myModel.address" [ngModelOptions]="{standalone: true}" [disabled]="isTheLoggedInUserAdmin" [data]="{ field: 'address', label: 'Address' }">
  <MyControl [(ngModel)]="myModel.title"   [ngModelOptions]="{standalone: true}" [disabled]="isTheLoggedInUserAdmin" [data]="{ field: 'title', label: 'Title' }">
  <MyControl [(ngModel)]="myModel.surname" [ngModelOptions]="{standalone: true}" [disabled]="isTheLoggedInUserAdmin" [data]="{ field: 'surname', label: 'Surname' }">
  <!-- other controls... -->
</div>

如果您有 model 描述數組,也可以輕松地將其寫入ngFor

編輯:添加示例 scss 樣式。

my-custom-control.component.scss

@import "variable.scss";

:host(.ng-dirty.ng-invalid, .ng-touched.ng-invalid) input {
  border-color: $c-alert !important;
  border-width: 2px;
  border-style: solid;
  color: $c-alert;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM