Ich habe meine Angular2 RC5-Anwendung auf RC6 aktualisiert. Ich habe einige benutzerdefinierte Formularsteuerelemente basierend auf this Tutorial von Thoughttram entwickelt.Angular2- RC6 Custom Form Controls funktioniert nicht
Alles funktionierte bis RC5, aber nach dem Update funktioniert die Validierung nicht mehr, nach ein wenig Nachforschung fand ich heraus, dass der Wert des Steuerelements nicht im zugehörigen Modell widergespiegelt wird.
Sie können die Original-Plombe aus Thoughttrams Tutorial here finden.
Um das Problem zu aktualisieren, um die Versionsinformationen in systemjs.config.js
Datei von
var ngVer = '@2.0.0-rc.5';
var routerVer = '@3.0.0-rc.1';
var formsVer = '@0.3.0';
var routerDeprecatedVer = '@2.0.0-rc.2';
zu
var ngVer = '@2.0.0-rc.6';
var routerVer = '@3.0.0-rc.2';
var formsVer = '@2.0.0-rc.6';
zu reproduzieren Nachdem die Version, die Sie sehen, aktualisieren wird, dass der Steuerwert nicht aktualisiert wird, und aufgrund dieser die Validierung funktioniert nicht.
Wenn ich jedoch die eckige Version auf @2.0.0-rc.6
aktualisiere und die Formularversion intakt halte, d. H. @0.3.0
, funktioniert es.
UPDATE 1:-Code für die Komponente
import { Component, OnInit, forwardRef, Input, OnChanges } from '@angular/core';
import { FormControl, ControlValueAccessor, NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
export function createCounterRangeValidator(maxValue, minValue) {
return (c: FormControl) => {
let err = {
rangeError: {
given: c.value,
max: maxValue || 10,
min: minValue || 0
}
};
return (c.value > +maxValue || c.value < +minValue) ? err: null;
}
}
@Component({
selector: 'counter-input',
template: `
<button (click)="increase()">+</button> {{counterValue}} <button (click)="decrease()">-</button>
`,
providers: [
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => CounterInputComponent), multi: true },
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => CounterInputComponent), multi: true }
]
})
export class CounterInputComponent implements ControlValueAccessor, OnChanges {
propagateChange:any =() => {};
validateFn:any =() => {};
@Input('counterValue') _counterValue = 0;
@Input() counterRangeMax;
@Input() counterRangeMin;
get counterValue() {
return this._counterValue;
}
set counterValue(val) {
this._counterValue = val;
this.propagateChange(val);
}
ngOnChanges(inputs) {
if (inputs.counterRangeMax || inputs.counterRangeMin) {
this.validateFn = createCounterRangeValidator(this.counterRangeMax, this.counterRangeMin);
}
}
writeValue(value) {
if (value) {
this.counterValue = value;
}
}
registerOnChange(fn) {
this.propagateChange = fn;
}
registerOnTouched() {}
increase() {
this.counterValue++;
}
decrease() {
this.counterValue--;
}
validate(c: FormControl) {
return this.validateFn(c);
}
}
Hauptmodul wie folgt aussieht:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { CounterInputComponent } from './counter-input.component.ts';
@NgModule({
imports: [BrowserModule, FormsModule, ReactiveFormsModule],
declarations: [AppComponent, CounterInputComponent],
bootstrap: [AppComponent]
})
export class AppModule {}
und ich bin die Komponente in meinem app.component wie
import { Component } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { createCounterRangeValidator } from './counter-input.component';
@Component({
selector: 'my-app',
template: `
<h2>Inside Form</h2>
<div>
<label>Change min value:</label>
<input [(ngModel)]="minValue">
</div>
<div>
<label>Change max value:</label>
<input [(ngModel)]="maxValue">
</div>
<form [formGroup]="form">
<p>Control value: {{form.controls.counter.value}}</p>
<p>Min Value: {{minValue}}</p>
<p>Max Value: {{maxValue}}</p>
<p>Form Value:</p>
<pre>{{ form.value | json }}</pre>
<counter-input
formControlName="counter"
[counterRangeMax]="maxValue"
[counterRangeMin]="minValue"
[counterValue]="50"
></counter-input>
</form>
<p *ngIf="!form.valid">Form is invalid!</p>
<h2>Standalone</h2>
<counter-input
counterMinValue="0"
counterMaxValue="3"
[counterValue]="counterValue"></counter-input>
`
})
export class AppComponent {
form:FormGroup;
counterValue = 3;
minValue = 0;
maxValue = 12;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.form = this.fb.group({
counter: this.counterValue
});
}
}
mit
Update 2: Ich habe dieses Problem auf Github gemeldet here
Wie man sehen kann ich keine veraltete Sache im Quellcode bin mit zur Verfügung gestellt. Es ist also ein anderes Problem, glaube ich. –
Hier gibt es einen Unterschied. Meine Komponente ist ein benutzerdefiniertes Formularsteuerelement, das basierend auf dem Wert ein Formular gültig/ungültig machen kann. In diesem Fall schreiben Sie eine benutzerdefinierte Komponente. Das Problem, dem ich gegenüberstehe, wird nur angezeigt, wenn Sie ein benutzerdefiniertes Formularsteuerelement schreiben. Der Link zu den benutzerdefinierten Formularsteuerelementen ist http://blog.thoughttram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html –
Okay ... aber ich sehe nicht die Unterscheidung zwischen den beiden. Ich erlaube nur gültige Werte in der Kindkomponente, so dass ihre Ausgabe immer gültig ist. –