Обновление значения Angular 6 Form в случае изменения внешнего значения соответствующего элемента dom внешней библиотекой - PullRequest
0 голосов
/ 02 сентября 2018

Я экспериментирую с совместным просмотром форм Angular 6. При совместном просмотре библиотеки с открытым исходным кодом JS обновляет значение DOM соответствующего элемента для удаленной стороны. Я обновил вместе связанный с JS код в index.html (две строки одна в голове, а другая в тело) Я наблюдал, используя ControlValueAccessor Тип формы Значение DOM соответствующего элемента обновляется, но значение FormControl не обновляется в представлении. Мой вопрос заключается в том, как изменения, внесенные внешней библиотекой для элементов DOM, могут быть отражены в представлении углового значения элемента управления формы 6.

Код можно получить по ссылке ниже: https://github.com/srigaurav1986/Angular-Forms.git

Как воспроизвести:
1.Скачать код с вышеуказанной ссылки.
2.Установите зависимости, используя "npm install"
3. Выполнить "ng serve -o"
4.открыто в браузере "http://localhost:4200/controlvalueaccessor"
5.Нажмите «Начать вместе»
6. Скопируйте ссылку в другом окне браузера.
7. Обновите поле «Имя»

Мы видим, что значение поля DOM также обновляется на удаленной стороне, но после нажатия кнопки «Отправить» мы видим, что значение FormControl остается неизменным на удаленной стороне, но изменяется на другой стороне.

Я попытался использовать ручное обнаружение изменений, используя application.tick, markforcheck () и detechanges () apis, но безуспешно. Есть способ, где мы можем прослушать какое-то событие об изменении элемента DOM и подписаться на него, а также обновить Значения параметра Formcontrol в таком случае.

1 Ответ

0 голосов
/ 20 сентября 2018

Ответ на этот вопрос заключается в свойстве angular (6), которое работает с теневым DOM и прослушивает только изменения, происходящие в угловой зоне, когда сторонняя библиотека, такая как TogetherJS, обновляет соответствующие изменения DOM, не влияя на угловые компоненты, так как они не подписаны на фактический собственный элемент DOM.

enter image description here

Чтобы решить эту проблему, мы сделали следующее:

  • Зарегистрируйте один обратный вызов в конструкторе класса 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 для прочтения других.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...