Плагины Ionic V2 и Cordova - Uncaught TypeError: невозможно установить для свойства «тест» значение null

Я использую Ionic v2 и плагин сканера штрих-кода Phonegap.

При выполнении функции scanBarcode() ниже я получаю сообщение об ошибке:

Uncaught TypeError: Cannot set property 'test' of null

at

this.test = result.text;

код:

import {Page} from 'ionic-angular';


@Page({
  templateUrl: 'build/pages/scanBarcode/scanBarcode.html'
})
export class ScanBarcode {
  constructor() {
    this.test = "";
  }

  scanBarcode(){
    cordova.plugins.barcodeScanner.scan(
      function (result) {
        console.log(result.text);
        this.test = result.text;
        console.log("SB result" + test);
      },
      function (error) {
        alert("Scanning failed: " + error);
      }
    )
  }
}

Первый console.log не содержит ошибок и показывает правильную информацию:

console.log(result.text);

person Neil Hoff    schedule 31.03.2016    source источник
comment
На первый взгляд похоже на проблему с закрытием JS... Или, может быть, вам нужна промежуточная ссылка: somevar = result; тест = некоторая переменная.текст; это.тест = тест;   -  person Christian Bonato    schedule 01.04.2016


Ответы (1)


Проблема с вашим кодом заключается в том, что вы пытаетесь получить доступ к указателю this вашего класса внутри функции результата метода сканирования.

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

scanBarcode(){

  //Create 'self' variable outside the scan function, assigning 'this' to it
  let self = this;

  cordova.plugins.barcodeScanner.scan(
    function (result) {
      console.log(result.text);
      //Use 'self' instead of 'this' to access 'test'
      self.test = result.text;
      console.log("SB result" + test);
    },
    function (error) {
      alert("Scanning failed: " + error);
    }
  )
}

Объяснение

Когда вы вызываете функцию .scan(), вы даете ей два обратных вызова. Вы не можете использовать this для выполнения того, что хотите, потому что в Javascript это имеет контекст вызывающей функции.

Обычно, когда вы обращаетесь к «этому» внутри обратного вызова, оно имеет контекст «окна». Это потому, что когда вы (определяете и) вызываете функцию без контекста объекта, вы фактически используете контекст «окна». Пример:

function fun(){ console.log('this = window; in here');
fun();

На самом деле происходит следующее:

window.fun = function() { /* ... */ }
window.fun(); 

(Для получения дополнительной информации об этом прочитайте о модели объектной ориентации на основе прототипа javascript)

В этом случае у вас будет ошибка Невозможно установить свойство 'test' of undefined. Но, поскольку ваш обратный вызов вызывается непосредственно плагином Cordova, я считаю, что «это» вообще не имеет контекста (хотя я не уверен).

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

Наконец, поскольку обратный вызов — это замыкание, а замыкание запоминает среду, в которой оно было создано, обратный вызов знает о существовании переменной self. Вот почему вы можете использовать его в этом случае.

person igor.araujo    schedule 01.04.2016