2017-02-14 7 views
0

Я использую npm-mqtt для получения данных от другого брокера mqtt.Свойства класса доступа за пределами области обратного вызова mqtt

При каждом полученном сообщении я хочу добавить данные в свойство класса/компонента.

Но я не могу получить доступ к классу или его свойствам. Вместо этого область указывает, что я являюсь объектом класса клиента mqtt.

Вот пример кода:

this.mydata: Array<any> = []; 

private fetchWithMqtt(){ 
var client = mqtt.connect('ws://' + this.ip + ":" + Number(this.port) + "/mqtt"); 
     // set callback handlers 
     client.on('close', this.onConnectionLost); 
     client.on('message', this.onMessageArrived); 
     client.on('connect', this.onConnect); 
} 

private onMessageArrived(topic, message) { 
     let tempDataset = JSON.parse(message).dataset; 
      this.mydata.push({ //this.mydata is undefined because this = mqtt-client 
       x: tempDataset[0], 
       y: tempDataset[1] 
      }); 

Как я могу передавать данные моего класса собственности вне этой сферы?

ответ

1

Используя .bind(this), вы можете быть уверены, что this не изменяется, когда вы вызываете события.

Ваш код будет выглядеть так:

this.mydata: Array<any> = []; 

private fetchWithMqtt(){ 
    var client = mqtt.connect('ws://' + this.ip + ":" + Number(this.port) + "/mqtt"); 
    // set callback handlers 
    client.on('close', this.onConnectionLost.bind(this)); 
    client.on('message', this.onMessageArrived.bind(this)); 
    client.on('connect', this.onConnect.bind(this)); 
} 

private onMessageArrived(topic, message) { 
    let tempDataset = JSON.parse(message).dataset; 
    this.mydata.push({ 
     x: tempDataset[0], 
     y: tempDataset[1] 
    }); 

Но что, если вам нужно получить доступ к client внутри обработчика событий? Ну, тогда вы все равно можете использовать bind, но добавьте mydata к обработчику событий и возьмите его в качестве аргумента.

Ваш код теперь становится:

this.mydata: Array<any> = []; 

private fetchWithMqtt(){ 
    var client = mqtt.connect('ws://' + this.ip + ":" + Number(this.port) + "/mqtt"); 
    // set callback handlers 
    client.on('close', this.onConnectionLost.bind(client, this.mydata)); 
    client.on('message', this.onMessageArrived.bind(client, this.mydata)); 
    client.on('connect', this.onConnect.bind(client, this.mydata)); 
} 

private onMessageArrived(mydata, topic, message) { 
    let tempDataset = JSON.parse(message).dataset; 
    mydata.push({ // this == client 
     x: tempDataset[0], 
     y: tempDataset[1] 
    }); 
+0

Ваш второй подход является копией по ссылке, а не по значению? В противном случае это не будет работать должным образом. – Wandang

+1

Мой второй подход пропускает 'this.mydata' по ссылке и в момент ссылки' this' по-прежнему является вашим экземпляром класса, а не mqtt. Таким образом, это просто добавление 'this.mydata' к любому вызову, но текущий контекст, когда триггеры событий не имеют значения, потому что мы всегда добавляем один и тот же массив. Я бы пошел с первым решением как можно чаще, но если вам нужен был доступ к клиенту по какой-то причине, я хотел бы обязательно опубликовать обходной путь. –

Смежные вопросы