2017-01-29 7 views
1

Я попытался написать собственный пользовательский компонент, который имеет базовую валидацию с регулярным выражением, которое может быть задано в качестве входных данных для компонента. Есть два случая: тот, где форма сначала пуста (форма нового элемента), а другая - там, где все там (редактировать).Как реализовать ngOnChanges для проверки ввода на угловом 2 без запуска «Выражение изменилось после его проверки». error

Проблема в том, что когда я пытаюсь проверить поля после того, как данные изначально установлены, обычно я получаю выражение «Expression» после его проверки ». Я понимаю, почему эта проверка выполнена и почему возникает ошибка, но я просто не понимаю, что это за точка 'ngOnChanges', если я не могу изменить состояние компонента из нее? В этом случае изменение состояния - это логический флаг isValid, который заставляет границы компонентов становиться красными.

Я попытался следующие:

  • this.changeDetect.detectChanges(), до и после того, как на ngOnChanges.
  • изменить 'текст' как геттер/сеттер. Переместите валидацию там. такая же ошибка. Я думаю, что это в основном то же, что и у ngOnChanges, поэтому никаких сюрпризов нет.
  • ngAfterViewInit не проверяет случай, когда форма обновления кода (для примера , запрос из концов бэкэнда -> форма редактирования заполнена.) Ошибка не возникает.
  • комплект изменениеDetection stragedy как нажимайте на @Component декоратор.
  • таймауты ... без изменений, если я установил тайм-аут через 1 сек. Ничего не происходит, если отсутствует ошибка. Вероятно, это связано с проверкой режима разработки , которая, кажется, происходит через 1 секунду после первоначального изменения.

Это очень распространенный и простой случай использования, и по этой причине я думаю, что я пропустил что-то очень простое здесь.

Пример использования:

<cx-form-text-input validate=".+" label="Rekisterinumero*" [(text)]="ticket.registerPlate" format="uppercase"></cx-form-text-input> 

Пример Компонент:

@Component({ 
    selector: 'cx-form-text-input', 
    templateUrl: './form-text-input.component.html', 
    styleUrls: ['./form-text-input.component.scss'] 
}) 
export class FormTextInputComponent implements OnChanges { 
    @Input() 
    public text: string; 

    @Output() textChange = new EventEmitter(); 

    @Input() public validate; 

    @Input() public label: string = 'DEFAULT LABEL'; 

    @Input() public disabled = false; 

    @Input() format: string; 

    public entry: FormEntry; 

    constructor(private form: FormContext, private changeDetect: ChangeDetectorRef) { 
    this.entry = form.Join(); 
    } 

    private applyFormat(text: string): string { 
    switch (this.format) { 
     case 'uppercase': 
     return text.toUpperCase(); 
     default: 
     return text; 
    } 
    } 

    public isDisabled(): boolean { 
    return this.disabled || this.form.disabled; 
    } 

    public keyboardEvent() { 
    this.entry.isDirty = true; 
    this.text = this.applyFormat(this.text); 
    this.validateData(); 

    this.textChange.emit(this.text); 
    } 

    private validateData() { 
    if (!this.validate) { 
     this.entry.isValid = true; 
     return; 
    } 

    if (!this.text) { 
     this.entry.isValid = false; 
     return; 
    } 

    this.entry.isValid = !!this.text.match(this.validate); 
    } 

    ngOnChanges(changes: SimpleChanges) { 
    this.validateData(); // The painpoint... 
    } 
} 

Ошибка:

EXCEPTION: Error in ./EditFormComponent class EditFormComponent - inline template:6:72 caused by: Expression has changed after it was checked. Previous value: 'true'. Current value: 'false'. 
ORIGINAL EXCEPTION: Expression has changed after it was checked. Previous value: 'true'. Current value: 'false'. 
ORIGINAL STACKTRACE: 

ответ

1
ngOnChanges(changes: SimpleChanges) { 
    this.validateData(); // The painpoint... 
    this.changeDetect.detectChanges(); // <<<=== invoke change detection at the end of `ngOnChanges` if the model was modified 
    } 
+0

Пытались, что Allready, https://i.imgur.com/PnVsfpt .png, никакой помощи. Так что это должно сработать? Если так, я думаю, что в моем коде может быть что-то еще, что вызывает его. Или это ошибка в угловом 2. Однако я использовал от 2.1 -> 2.4, и это все еще происходит. – savpek

+0

Сообщение об ошибке - 'EditFormComponent', а код в вашем вопросе показывает' FormTextInputComponent'. Мой ответ работает только тогда, когда изменение влияет только на модель текущего класса ('FormTextInputComponent'). Вы можете попробовать ввести «private appRef: ApplicationRef» и вызвать 'this.appRef.tick()'. –

+0

Хм да, это хорошая точка! Я проверю, что завтра, если я смогу отслеживать цепочку обратно в EditFormComponent и выяснить, что вызывает ошибку после проверки. – savpek

 Смежные вопросы

  • Нет связанных вопросов^_^