![](/img/trans.png)
[英]How to get ng-template and ngModel in component using contentChild
[英]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.