Angular2 и Web Midi

#angular #typescript

#angular #машинописный текст

Вопрос:

Я новичок в Typescript и пытаюсь использовать Angular2 для создания веб-Midi-приложения, но у меня возникают некоторые проблемы с пониманием определенных ошибок. Я считаю, что я должен помещать Midi-функции внутри сервиса, но поправьте меня, если я ошибаюсь.

Приведенный ниже пример работает, когда midi-переменная и функция onMIDIMessage находятся вне

 var midi:any;

function onMIDIMessage(event) {
        console.log("msg received", event);
}

export class MidiService {

    onMidiInit() {
        if (navigator.requestMIDIAccess) {
            navigator.requestMIDIAccess({
                sysex: false
            }).then(this.onMIDISuccess, this.onMIDIFailure);
        } else {
            alert("No MIDI support in your browser.");
        }
    }

    onMIDISuccess(midiAccess) {
        console.log('MIDI Access Object', midiAccess);
        midi = midiAccess;
        console.log(midi);

        var inputs = midi.inputs.values();
        for (var input = inputs.next(); input amp;amp; !input.done; input = inputs.next()) {
            input.value.onmidimessage = onMIDIMessage;
        }

    }

    onMIDIFailure(e) {
        console.log(e);
    }
}
 

Все хорошо, и я могу распечатать входящие MIDI-сообщения с помощью этого. Однако я не понимаю, что, когда функция onMIDIMessage и midi-переменная находятся внутри класса MidiService, Chrome выдает ошибку. Почему это происходит?

midi.service.ts: 24 Не перехвачено (в обещании) Ошибка типа: не удается прочитать свойство>’onMIDIMessage’ неопределенного значения в MidiService.onMIDISuccess (http://localhost:3000/app/midi.service.js:27:57 )

 var midi:any;

// Code that does not work
export class MidiService {

    onMidiInit() {
        if (navigator.requestMIDIAccess) {
            navigator.requestMIDIAccess({
                sysex: false
            }).then(this.onMIDISuccess, this.onMIDIFailure);
        } else {
            alert("No MIDI support in your browser.");
        }
    }

    onMIDISuccess(midiAccess) {
        console.log('MIDI Access Object', midiAccess);
        midi = midiAccess;
        console.log(midi);

        var inputs = midi.inputs.values();
        for (var input = inputs.next(); input amp;amp; !input.done; input = inputs.next()) {
            input.value.onmidimessage = this.onMIDIMessage;
        }

    }

    onMIDIMessage(event) {
        console.log("msg received", event);
    }

    onMIDIFailure(e) {
        console.log(e);
    }
}
 

—ПРАВИТЬ

Методы вызываются в файле app.component.ts.

 import {Component} from 'angular2/core';
import {MidiService} from './midi.service';

@Component({
    selector: 'my-app',
    template: '<h1>My First Angular 2 App</h1>',
    providers: [MidiService]
})
export class AppComponent { 
    constructor(midiService: MidiService) {
        midiService.onMidiInit();
    }
}
 

Комментарии:

1. Как и откуда вызываются эти методы?

2. При инициализации класса MidiService onMIDIMessage вызывается каждый раз, когда поступает входящее MIDI-сообщение от MIDI-устройства, подключенного к компьютеру.

Ответ №1:

Похоже this , не указывает на текущий экземпляр класса.

Добавить .bind(this) , когда вы передаете методы текущего класса в качестве обратных вызовов:

 input.value.onmidimessage = this.onMIDIMessage.bind(this);
 

Комментарии:

1. Спасибо! Однако Chrome по-прежнему выдает эту ошибку в консоли:

2. midi.service.ts:23 Неперехваченных (в обещании) Ошибка типа: не удается прочитать свойство ‘onMIDIMessage’ неопределенного значения

3. Вы добавили его в }).then(this.onMIDISuccess, this.onMIDIFailure); » нравится }).then(this.onMIDISuccess.bind(this), this.onMIDIFailure.bind(this)); » ?

4. Спасибо, это сработало! Есть идеи, в чем проблема для midi: также любая переменная? Помещение его в класс MidiService также приведет к той же ошибке.

5. Вам нужно использовать this.midi для доступа к переменной, когда она находится внутри класса.