2016-12-31 11 views
2

Я получаю очень странную ошибку, которую я исследовал, и у меня возникли проблемы с выяснением. Большинство всех предметов, которые я нашел, примерно год назад до окончательных изменений и не работают сейчас.2-сторонняя привязка между двумя компонентами работает только с первой буквой

Сообщение об ошибке

Выражение изменилось после того, как он был установлен. Предыдущее значение: «Angular2». Текущее значение: «Angular2x».

По какой-то причине он вытаскивает исключение, когда он привязывается к объекту в 2-х направлениях.

Я думаю, что ошибка происходит после запуска следующего кода.

ngDoCheck(){ 
    this.bindingPropertyChange.emit(this.bindingProperty) 
    } 

Я создал Plunker, чтобы воспроизвести ошибку. Plunker here

Кто-нибудь знает, почему это происходит? Если да, можете ли вы объяснить, почему это исключение бросается?

+0

Могу ли я предложить другой способ сделать это? – micronyks

+0

уверен, я хотел бы иметь возможность использовать этот элемент управления с двухсторонней привязкой. – JamTay317

+0

@ JamTay317, проверьте это: https://plnkr.co/edit/nSymAOlvkOSdUx22gdrL?p=preview – Milad

ответ

2

ngDoCheck ваша проблема, здесь почему:

ngDoCheck будет срабатывать, если что-то изменится внутри вашей модели.

После того, как вы набрали письмо, угловые начнут проверять везде (все приложение) на любые соответствующие изменения, а Angular запускает обнаружение изменений только один раз после изменения, и после этого не должно быть никаких обновлений (один способ передачи данных, только одна проверка).

Предположим, что обнаружение изменений выполнено (ngDoCheck) успешно и обновлено пользовательский интерфейс соответственно, НО в середине проверки вы неожиданно вносите изменения.

В режиме Dev, Angular2 запускает другой changeDetection после первого, чтобы убедиться, что ничего не изменилось после того, как первый, и потому что вы излучаемый это событие и изменить модель снова молча, угловой злится и бросает ошибку.

Однако, в Prod mode, Angular не запускает вторую проверку, поэтому вы не увидите эту ошибку в процессе производства, но ваше обновление модели (emit) не будет отражено в пользовательском интерфейсе (чтобы проверить это , просто добавьте ngCore.enableProdMode(); в файл main.ts, и ошибка исчезнет).

Вот несколько способов исправить это:

1- изменить стратегию, как в моем First Plunker, вы можете просто использовать объектные привязки и обойти эту проблему.

2 Отложите ваши изменения с SetTimeout, который будет работать еще обнаружение изменений и делает угловую счастливым:

ngDoCheck(){ 
    setTimeout(()=>{ 
     this.bindingPropertyChange.emit(this.bindingProperty) 
    }); 

    } 

Вот является plunker

3- Не используйте ngDoCheck и испускать ваши изменения в другой цикл с использованием (ввода) или (keyup) или аналогичных событий, что снова делает Угловой запуск другого обнаружения изменений:

ПРИМЕЧАНИЕ Я бы предложил использовать (ввод) по клавише или если вы используете keyup/keydown, обновление не будет плавным, потому что если вы нажмете клавишу и удерживаете ее там, обновление не произойдет, пока вы не отпустите ключ, но с), это происходит сразу, и, как вы сказали в комментарии, если пользователь должен был скопировать палочку с помощью мыши, они не используют ключ и не будут обновлять модель.

<input [(ngModel)]="bindingProperty" (input)="emitUp()" class="form-control"/> 

emitUp(){ 
    this.bindingPropertyChange.emit(this.bindingProperty) 
    } 

Вот Plunker

+1

Спасибо, это было очень полезно. Я не использовал ваш первый плункер, потому что я хочу повторно использовать этот элемент управления для имени, адреса, электронной почты ... и отправив объект и сказав obj.name, что кажется мне довольно статическим. Однако использование ввода делает шов как намного лучший вариант, чем оба других варианта. Поскольку это можно использовать повторно, и если пользователь должен был скопировать палочку с помощью мыши, они не используют ключ, и он не будет обновлять модель. – JamTay317

+0

@ JamTay317, Обновлен ответ и добавлена ​​более полезная информация, Cheers – Milad

1

Я не тот человек, чтобы сказать что-нибудь о ngDoCheck но, кажется, есть проблема с ngDoCheck. Кто-то еще может предложить это и может отредактировать мой ответ, чтобы что-нибудь сказать о ngDoCheck.

Но сейчас вы можете использовать keyup событие и связать функцию с ней, как показано ниже,

DEMO: https://plnkr.co/edit/hSrPuWNyJd6Az8sHXh1T?p=preview

<input [(ngModel)]="bindingProperty" (keyup)="check()" class="form-control"/> 

check(){ 
    this.bindingPropertyChange.emit(this.bindingProperty) 
} 

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

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