首页 > 解决方案 > 如何将 TypeScript 函数调用到 JQuery 函数中?

问题描述

我有一个问题,我无法在 Angular Instascan 库上安装,所以我在不安装的情况下使用它,只导入脚本。为了使它工作,我必须在组件中的 ts 文件中使用 JQuery,有没有办法在 JQuery 函数内部调用 Typescript 函数来将 QR 的内容发送到我的 Web 服务?我一直在尝试使用 Ajax 将数据直接发送到 Web 服务,但不起作用。

QR 的函数是 escanearQR,我要调用的函数是scanner.addListener 中的registrarAsistencia。

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { DatosService } from '../datos.service';
import Swal from 'sweetalert2';

declare var $: any;
declare var Instascan: any;
@Component({
  selector: 'app-toma-asistencia',
  templateUrl: './toma-asistencia.component.html',
  styleUrls: ['./toma-asistencia.component.css']
})
export class TomaAsistenciaComponent implements OnInit {

  constructor(private router: Router, public datos: DatosService) { }
  id_actividad_activa: string;
  id_evento_activo: string;
  actividad: any;
  participantes: any;
  qr:string;
  datosEscaner:string;

  obtenerParticipantes() {
    this.datos.getParticipantes(this.id_evento_activo, this.id_actividad_activa).subscribe(res => {
      this.participantes = res;
    }, error => {
      Swal.fire({
        icon: 'error',
        title: '¡Ups!',
        text: 'No hay participantes aún',
        timer: 2000
      });
    });
  }

  escanearQR(){
    $('#btnqr').empty();
    let scanner = new Instascan.Scanner({ video: document.getElementById('preview'), scanPeriod: 5, mirror: false });
                    scanner.addListener('scan', function(content){
            console.log(content);
            $('#codigoQR').val(content);
            //CALL HERE registrarAsistencia WITH content VALUE
                    });
                    Instascan.Camera.getCameras().then(function (cameras){
                        if(cameras.length>0){
                            scanner.start(cameras[0]);
                            $('[name="options"]').on('change',function(){
                                if($(this).val()==1){
                                    if(cameras[0]!=""){
                                        scanner.start(cameras[0]);
                                    }else{
                                        alert('No se ha encontrado camara frontal');
                                    }
                                }else if($(this).val()==2){
                                    if(cameras[1]!=""){
                                        scanner.start(cameras[1]);
                                    }else{
                                        alert('No se ha encontrado camara trasera');
                                    }
                                }
                            });
                        }else{
                            console.error('No se han encontrado camaras.');
                            alert('No se han encontrado camaras.');
                        }
                    }).catch(function(e){
                        console.error(e);
                        alert(e);
                    });
          
  }

  registrarAsistencia(){

  }

  cerrarEscaner(){
    window.location.reload();
  }

  ngOnInit(): void {
    this.id_actividad_activa = this.datos.getActividadActiva().id_ac;
    this.id_evento_activo = this.datos.getEventoActivo().id_evento;
    this.actividad = this.datos.getActividadActiva().nombre;
    this.obtenerParticipantes();
  }
}

标签: jqueryangulartypescriptinstascan

解决方案


您面临的问题与 Angular 无关,而是与 JavaScript 函数中的“this”范围有关。

让我们从头开始:使用“old”函数关键字声明的函数有点健忘。这意味着他们不记得在他们声明的上下文中this的值,他们在执行的上下文中使用this的值。

箭头函数(如果您熟悉 Java,则为 *lambda 函数)更强大:它们能够提醒 this 的值作为其声明的范围。在某种程度上,以下示例做同样的事情:

const bindedFn = (function() {}).bind(this);
const arrowFn = () => {};

据我在您的代码片段中看到的,您可以执行类似的操作

$(this).val();

所以我假设应该被jQuery用作执行的上下文。如何解决这个问题?好吧,如果你知道什么是闭包并且 JavaScript 中的每个函数都是一个闭包,那就很容易了。在扫描器变量之前声明一个 const : 将用于将this的值保存为您所在组件的实例,或者更简单的是,您的组件中的函数:

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { DatosService } from '../datos.service';
import Swal from 'sweetalert2';

declare var $: any;
declare var Instascan: any;
@Component({
  selector: 'app-toma-asistencia',
  templateUrl: './toma-asistencia.component.html',
  styleUrls: ['./toma-asistencia.component.css']
})
export class TomaAsistenciaComponent implements OnInit {

  constructor(private router: Router, public datos: DatosService) { }
  id_actividad_activa: string;
  id_evento_activo: string;
  actividad: any;
  participantes: any;
  qr:string;
  datosEscaner:string;

  obtenerParticipantes() {
    this.datos.getParticipantes(this.id_evento_activo, this.id_actividad_activa).subscribe(res => {
      this.participantes = res;
    }, error => {
      Swal.fire({
        icon: 'error',
        title: '¡Ups!',
        text: 'No hay participantes aún',
        timer: 2000
      });
    });
  }

  escanearQR(){
    $('#btnqr').empty();
    
    const registrarAsistencia = this.registrarAsistencia;
    
    let scanner = new Instascan.Scanner({ video: document.getElementById('preview'), scanPeriod: 5, mirror: false });
                    scanner.addListener('scan', function(content){
            console.log(content);
            $('#codigoQR').val(content);
            // CALL HERE registrarAsistencia WITH content VALUE
            registrarAsistencia(content);
                    });
                    Instascan.Camera.getCameras().then(function (cameras){
                        if(cameras.length>0){
                            scanner.start(cameras[0]);
                            $('[name="options"]').on('change',function(){
                                if($(this).val()==1){
                                    if(cameras[0]!=""){
                                        scanner.start(cameras[0]);
                                    }else{
                                        alert('No se ha encontrado camara frontal');
                                    }
                                }else if($(this).val()==2){
                                    if(cameras[1]!=""){
                                        scanner.start(cameras[1]);
                                    }else{
                                        alert('No se ha encontrado camara trasera');
                                    }
                                }
                            });
                        }else{
                            console.error('No se han encontrado camaras.');
                            alert('No se han encontrado camaras.');
                        }
                    }).catch(function(e){
                        console.error(e);
                        alert(e);
                    });
          
  }

  registrarAsistencia(){

  }

  cerrarEscaner(){
    window.location.reload();
  }

  ngOnInit(): void {
    this.id_actividad_activa = this.datos.getActividadActiva().id_ac;
    this.id_evento_activo = this.datos.getEventoActivo().id_evento;
    this.actividad = this.datos.getActividadActiva().nombre;
    this.obtenerParticipantes();
  }
}

要了解解决方案,请仔细阅读此链接 - javascript.info/closures。JavaScript.info 是一本供想要了解 JavaScript 工作原理的开发人员使用的圣经。请记住:TypeScript 只是 JavaScript 的超集,因此您必须深入了解后者才能正确编码第一个。


推荐阅读