Сканирующий сканер сканера QR-кода Instascan не обновляет представление компонента Angular 5 - PullRequest
0 голосов
/ 18 октября 2018

Я реализовал Instascan (https://github.com/schmich/instascan), чтобы позволить пользователям читать QR-коды из моего приложения Angular 5.

Я должен вызвать некоторые действия после успешного сканирования и обновить вид моего компонентасоответственно.

Я использую следующий код внутри моего компонента, чтобы обнаружить мои камеры и начать сканирование:

cameras: Array<any> = []
selectedCamera: any
scanner: any
content: string

ngOnInit () {
    let vm = this
    Instascan.Camera.getCameras().then(function (cameras) {
      if (cameras.length > 0) {
        vm.cameras.push(...cameras)
      } else {
        console.error('No cameras found.')
      }
    }).catch(function (e) {
      console.error(e)
    })
  }

startScan () {
    let vm = this
    this.scanner = new Instascan.Scanner({
      video: this.videoContainer.nativeElement,
      backgroundScan: false,
      mirror: false
    })
    this.scanner.addListener('scan', function (content) {
      vm.content = content
    })
    this.selectedCamera = this.cameras[0]
    this.scanner.start(this.selectedCamera)
  }

И в моем шаблоне у меня есть элемент, который существует, только если 'content'существует, и при щелчке отправляет отсканированное содержимое в родительский компонент через EventEmitter:

<div *ngIf="content" class="btn" (click)="emitContent()">
          PROCEED
        </div>

Проблема заключается в том, что при обратном вызове события 'scan' изменения в 'content', похоже, не применяются кмое представление и кнопка «ПРОЦЕДУРА» не становятся видимыми. Происходит еще более странное поведение: после нажатия в любом месте экрана эти изменения применяются к моему представлению.

Я также пытался использовать ChangeDetectorRefМетод .detectChanges () внутри обратного вызова и привязка 'this' к обратному вызову, но оба они не работают.

Как мне решить эту проблему?

Спасибо!

1 Ответ

0 голосов
/ 18 октября 2018

Мне удалось решить эту проблему с помощью NgZone следующим образом:

import { NgZone } from '@angular/core'

constructor (
    private ngZone: NgZone
  ) {}

startScan () {
    this.scanner = new Instascan.Scanner({
      video: this.videoContainer.nativeElement,
      backgroundScan: false,
      mirror: false
    })
    this.scanner.addListener('scan', function (content) {
      this.ngZone.run(() => {
        this.content = content
      })
    }.bind(this))
    this.selectedCamera = this.cameras[0]
    this.scanner.start(this.selectedCamera)
  }

Я не знаю, является ли это лучшим решением, и на самом деле я не знаю, как использование NgZone влияет напроизводительность / состояние приложения вообще.

Если кто-то знает лучшее решение, оно будет приветствоваться!

Спасибо!

...