Ответ на этот вопрос заключается в свойстве angular (6), которое работает с теневым DOM и прослушивает только изменения, происходящие в угловой зоне, когда сторонняя библиотека, такая как TogetherJS, обновляет соответствующие изменения DOM, не влияя на угловые компоненты, так как они не подписаны на фактический собственный элемент DOM.
Чтобы решить эту проблему, мы сделали следующее:
- Зарегистрируйте один обратный вызов в конструкторе класса Form для захвата событий DOM « change », инициированных из библиотеки совместного просмотра, то есть происходящих вне угловой зоны, как указано ниже:
Фрагмент кода
constructor(private formBuilder: FormBuilder,private elementRef: ElementRef,private _renderer: Renderer,private cdr:ChangeDetectorRef,private app:ApplicationRef,private zone:NgZone) {
zone.runOutsideAngular(() =>{
window.document.addEventListener('change', this.change.bind(this));
})
}
- Определите eventHandler для выполнения следующих действий:
- Запуск в контексте Angular с использованием this.zone.run ()
- Используйте ElementRef, чтобы получить селектор шаблона компонента.
- Запустите queryselector для элементов ввода и сравните с событием externalHTML, чтобы проверить, какой элемент изменился в компоненте.
- Установите значение Formcontrol для соответствующего элемента.
PS: здесь customerForm - это тип экземпляра ControlValueAccesor FormGroup. В вашем случае это может быть ваша форма. Мы можем обобщить форму (в случае реактивного) обхода ключа, как упомянуто в другом посте SO
Angular 2: перебрать элементы управления реактивной формы
Фрагмент кода:
change(event){
event.preventDefault();
console.log("DOM value changed" ,event);
console.log("component value", this.elementRef.nativeElement);
this.zone.run(() => { console.log('Do change detection here');
//this.cdr.detectChanges();
if(this.elementRef.nativeElement.querySelectorAll('input')[0].outerHTML === event.target.outerHTML)
{
console.log('Inside value updation');
//this.customerForm.controls.name.value=event.target.value;
this.customerForm.controls['name'].setValue(event.target.value);
}
});
setTimeout(() =>{
this.cdr.markForCheck();
})
}
Это установит соответствующие значения элементов (очевидно, через цикл обхода), измененных в компоненте, и проверка не должна завершиться сбоем, как это происходит в текущем контексте.
Основная идея вышеприведенных деталей заключается в том, как фиксировать события изменения, происходящие за пределами угловой зоны, и соответственно обновлять угловое приложение.
PS: Я обновлю полный код в github для прочтения других.