typescript - İç İçe Bir Bileşen ile Angular Formu Nasıl Gönderilir
Tüm uygulama boyunca kullanacağım bir dateTime bileşeni yaptım. Ayrı bir bileşende bir formu göndermek için kullandığım bir formGroup var ve bu bileşenin o formun bir parçası olmasını istiyorum. Alt formdan veriyi ebeveyn formda göstermekte sorun yaşıyorum. Bunu ebeveyn formun bir özelliği/değeri olarak ayarlamanın bir yolu var mı?
Çocuk TarihSaat Seçici HTML:
<mat-form-field>
<input matInput [ngxMatDatetimePicker]="picker" placeholder="{{ name }}" [formControl]="dateControl" required="true">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<ngx-mat-datetime-picker #picker startView="year"></ngx-mat-datetime-picker>
</mat-form-field>
Çocuk Typescript:
@Input() name: string;
@Input() displayTime: boolean;
@Input() allowDateInPast: boolean;
public dateControl = new FormControl();
constructor() { }
ngOnInit() {
}
Üst HTML/form:
<form [formGroup]="formGroup">
<mat-label>Name</mat-label>
<input type="textfield" formControlName="reportName" matInput required="true" placeholder="Report Name" name="reportName">
</mat-form-field>
<div class="col-sm">
<app-datetime-picker [name]="'Start Date'" [displayTime]="true" [allowDateInPast]="true"></app-datetime-picker>
</div>
<button class="float-right" [disabled]="formGroup.invalid" (click)="createReport()" mat-raised-button color="primary">Save</button>
</div>
</form>
Ana Typescript:
formGroup: FormGroup = new FormGroup({
reportName: new FormControl("", Validators.required),
// ?? something here
});
Bu mümkün mü? Bunu yaparken @Output() kullanmam gerekir mi?
Her türlü yardım için teşekkürler.
Travis W-
Cevap #1
Genellikle yaptığım şey, FormControl'ü bir input olarak göndermektir. Yani alt bileşende bir inputa sahip olursunuz: @Input() dateControl: FormControl;
Üst HTML dosyanızda FormControl'ü şu şekilde geçirirsiniz: <app-datetime-picker [dateControl]="formGroup['dateControl']">
Artık FormControl'ün özelliklerini normal şekilde üst bileşende okuyabilirsiniz.
Ben de diğer cevaplara katılıyorum, kontrol değeri erişicisi bunun için iyi bir çözüm olurdu, ama uygulaması biraz daha zor.
Cevap #2
Form kontrolü olarak kullanılmasını istediğiniz için app-datetime-picker bileşeninizde ControlValueAccessor uyguladığınızdan emin olurdum. Bu, onu bir <input> veya <select> gibi kullanmanıza olanak tanıyacaktır.
Tarih seçici kontrolünüz bundan biraz böyle görünecek:
@Component({
selector: 'app-datetime-picker',
templateUrl: './app-datetime-picker.html',
styleUrls: ['./app-datetime-picker.css'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DateControlPicker),
multi: true
}
]
})
export class DateTimePicker implements ControlValueAccessor {
disabled = false;
innerValue: Date;
//Make sure your template calls this function to update the value
valueChanged(obj: Date) {
this.writeValue(obj); //save the value so this component can render it
this.onChangeCallback(obj); //update the form
}
//satisfy the ControlValueAccessor interface
//the forms library will call this when the form is first initialized or when the control is updated by the code "myFormGroup.controls['someControlName'].patchValue(new Date())"
writeValue(obj: any): void {
this.selectedValue = obj;
}
//Register a callback - this callback function is what we neeed to call to update that form
registerOnChange(fn: any): void {
this.onChangeCallback = fn;
}
registerOnTouched(fn: any): void {
this.onTouchedCallback = fn;
}
setDisabledState(isDisabled: boolean): void {
this.disabled = isDisabled;
}
private onTouchedCallback: () => void = () => {
};
private onChangeCallback: (_: any) => void = () => {
};
}
Sonra bunu bir form içeren şablonda kullanabilirsiniz:
<form [formGroup]="myFormGroup">
<app-datetime-picker formControlName="myControlName"></app-datetime-picker>
</form>
Form grubunu oluşturmak için kod arkası:
constructor(private formBuilder: FormBuilder){}
ngOnInit(){
this.myFormGroup = this.formBuilder.group({
myDateControlName: new FormControl(new Date());
})
}
