Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access 'this' in angular 2 event handler?

Tags:

angular

In my Component's keydown event handler, I need to modify a propery of the component via this:

  canvasKeyHandler (event) {
    console.log('vrscene.canvasKeyHandler: event.keyCode=' + event.keyCode);
    console.log('vrscene.canvasKeyHandler: self.dolly' + this.dolly);

    CameraKeypressEvents.keyHandler(event, this.dolly) // <-- do something with this.dolly

But this.dolly is set to undefined:

vrscene.canvasKeyHandler: self.dollyundefined

vrscene.html:

<div class="container" id ="canvas-container-2">
   <canvas id="vrruntime-view"
           class="camera-keypress-events"
           tabindex="1"
           (keydown)="canvasKeyHandler($event)"
           style="border: 1px solid black;"
           >
   </canvas>
           <!--camera-keypress-events [cubeScene]="cubeScene" -->

</div>

vrscene.ts:

import {Component} from 'angular2/core';
import {Injectable} from 'angular2/core';
import WebGLRenderer = THREE.WebGLRenderer;
import {VRRenderer} from '../vrrenderer/vrrenderer'
import {CameraKeypressEvents} from '../camera-keypress-events/camera-keypress-events'

import Object3D = THREE.Object3D;
import Scene = THREE.Scene;
import PerspectiveCamera = THREE.PerspectiveCamera;
import Mesh = THREE.Mesh;
import VRControls = THREE.VRControls;
import VREffect = THREE.VREffect;

@Component ({
  selector: 'vrscene',
  templateUrl: 'app//vrscene/vrscene.html',
})

@Injectable()
export class VRScene {

  private _scene: Scene;
  camera: PerspectiveCamera;
  dolly: Object3D;
  vrControls: VRControls;
  vrEffect: VREffect;
  webVrManager;
  sphere: Mesh;
  cube: Mesh;
  BaseRotation = new THREE.Quaternion();

  constructor() {}

  //initScene(width: number, height: number, renderer: VRRenderer) {
  init(width: number, height: number, vrRenderer: VRRenderer) {
    console.log('VRScene.init: entered')
    this.scene = new THREE.Scene;

    this.camera = new THREE.PerspectiveCamera(75, width / height);
    this.camera.position.set(0, 1.5, 100);
    this.dolly = new THREE.Object3D();
    this.dolly.position.z = 50;
    this.scene.add(this.dolly);
    //
    this.dolly.add(this.camera);

    this.vrControls = new THREE.VRControls(this.camera);

    this.vrEffect = new THREE.VREffect(vrRenderer.renderer);
    this.vrEffect.setSize(width, height);
    this.webVrManager = new (<any>window).WebVRManager(vrRenderer.renderer, this.vrEffect);
    console.log('VRScene.init: this.webVrManager=' + this.webVrManager);
    this.camera.quaternion.copy(this.BaseRotation);

    var geometry = new THREE.BoxGeometry(25, 25, 25);
    var meshParms = new Object();

    meshParms['color'] = 0xff8000;

    var material = new THREE.MeshBasicMaterial(meshParms);
    //material = new THREE.MeshBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} );
    this.cube = new THREE.Mesh(geometry, material);
    this.scene.add(this.cube);

    // draw!
    vrRenderer.canvas.focus();
    //CubeOnPlaneScene.prototype.mainLoop.bind(this)
    // bind the 'this' of the canvasKeyHandler to the definition-time 'this'
    //VRScene.prototype.canvasKeyHandler.bind(this)
  }

  canvasKeyHandler (event, dolly) {
    console.log('vrscene.canvasKeyHandler: event.keyCode=' + event.keyCode);
    //console.log('vrscene.canvasKeyHandler: this.dolly' + this.dolly);
    //console.log('vrscene.

canvasKeyHandler: self.dolly' + this.dolly);
    console.log('vrscene.canvasKeyHandler: dolly' + dolly);

    //CameraKeypressEvents.keyHandler(event, this.dolly)
    //CameraKeypressEvents.keyHandler(event, VRScene.prototype.canvasKeyHandler)
    CameraKeypressEvents.keyHandler(event, dolly)
  }

  doIt() : string {
    return 'hello from VRScene'
  }

  // getters  and setters
  get scene():Scene {
     return this._scene;
  }

  set scene(scene: Scene) {
    if (scene === undefined) throw 'Please supply a scene';
    this._scene = scene;
  }

}

Key handler:

import {Directive} from 'angular2/core';
import {CubeScene} from '../cube-scene/cube-scene';
import Object3D = THREE.Object3D;
import Vector3 = THREE.Vector3;
import {Base} from '../base/base';
import Quaternion = THREE.Quaternion;


@Directive({
  selector: '[camera-keypress-events]',
  providers: [],
  //host: {},
  host: {
    '(keypress)' : 'onKeypress($event)'
  },

})

export class CameraKeypressEvents {

  constructor() {}

  static CAMERA_MOVE_DELTA = 1.2;
  static CAMERA_ROT_DELTA = 5;

  static keyHandler (event, dolly: Object3D) {
    console.log('CameraKeypressEvents.keyHandler: event.keyCode=' + event.keyCode)
    console.log('CameraKeypressEvents.keyHandler: dolly=' + dolly)   
        switch( event.keyCode) {
      case 'S'.charCodeAt(0):
        console.log('you pressed s');
        //dolly.position.z += CAMERA_MOVE_DELTA;
        dolly.translateZ(this.CAMERA_MOVE_DELTA);
        console.log('dolly.postion.x=' + dolly.position.x);
      break;

      case 'W'.charCodeAt(0):
        //console.log('you pressed s');
        //this.dolly.position.z -= this.CAMERA_MOVE_DELTA;
        dolly.translateZ(-this.CAMERA_MOVE_DELTA);
        //console.log('this.do-ly.postion.x=' + this.dolly.position.x);
      break;

      case 'A'.charCodeAt(0):
        //this.dolly.position.x -= this.CAMERA_MOVE_DELTA;
        dolly.translateX(-this.CAMERA_MOVE_DELTA);
      break;

      case 'D'.charCodeAt(0):
        //console.log('you pressed s');
        //this.dolly.position.x += this.CAMERA_MOVE_DELTA;
        dolly.translateX(this.CAMERA_MOVE_DELTA);
        //console.log('this.dolly.postion.x=' + this.dolly.position.x);
      break;

      case 'N'.charCodeAt(0):
        //this.dolly.position.y -= this.CAMERA_MOVE_DELTA;
        dolly.translateY(-this.CAMERA_MOVE_DELTA);
      break;

      case 'P'.charCodeAt(0):
        //console.log('you pressed s');
        //this.dolly.position.y += this.CAMERA_MOVE_DELTA;
        //console.log('this.dolly.postion.x=' + this.dolly.position.x);
        dolly.translateY(this.CAMERA_MOVE_DELTA);
      break;

      case 'Q'.charCodeAt(0):
        var tmpQuat = (new THREE.Quaternion()).setFromAxisAngle( new THREE.Vector3(0,1,0), Base.ONE_DEG * this.CAMERA_ROT_DELTA);
        dolly.quaternion.multiply(tmpQuat);
      break;

      case 'E'.charCodeAt(0):
        var tmpQuat = (new THREE.Quaternion()).setFromAxisAngle( new THREE.Vector3(0,1,0), Base.ONE_DEG * -this.CAMERA_ROT_DELTA);
        dolly.quaternion.multiply(tmpQuat);
      break;
    };
  }

   onKeypress (event, cubeScene) {
    console.log('CameraKeypressEvents.onKeypress: event.keyCode=' + event.keyCode)
        //event.preventDefault();
    console.log('vtClass.canvasKeyhandler: cubeScene=' + cubeScene);
    console.log(event, event.keyCode, event.keyIdentifier);

    /*
    */
  }
}

How do I either:

A) pass the instance on the keyhandler call?

I tried:

(keydown)="canvasKeyHandler($event,{{dolly}})"

B) Bind the canvasKeyHandler method to the compile time this?

I tried:

// bind the callback 'this' of the canvasKeyHandler to the definition-time 'this'
VRScene.prototype.canvasKeyHandler.bind(this)

and

  canvasKeyHandler (event) {
    ...
}.bind(this)

My apologies if this is an obvious question, but I'm just learning the Angular 2 framework and getting a little overwhelmed at this point. Do I need to do something with @Input?

Many Thanks

like image 263
vt5491 Avatar asked Apr 22 '16 10:04

vt5491


People also ask

What is event handler in Angular?

In Angular 2, events such as button click or any other sort of events can also be handled very easily. The events get triggered from the html page and are sent across to Angular JS class for further processing. Let's look at an example of how we can achieve event handling.

Can I use addEventListener in Angular?

Angular Renderer2. If we want to listen to a mousemove event on some native DOM element and invoke its callback function, onMouseMove , we would call the . addEventListener in the following way: nativeElement. addEventListener("mousemove", onMouseMove);

What's $event in Angular?

The $event object often contains information the method needs, such as a user's name or an image URL. The target event determines the shape of the $event object. If the target event is a native DOM element event, then $event is a DOM event object, with properties such as target and target.

What is Onclick in Angular?

Introduction to AngularJs onclick The ng-click directive can be used with multiple HTML elements such as button, input, select, checkbox, etc. This provides the developer ability to define custom behavior whenever an element is clicked.


2 Answers

(keydown)="canvasKeyHandler($event,{{dolly}})"

should be

(keydown)="canvasKeyHandler($event,dolly)"

I don't know if this actually fixes your problem (don't really understand what the issue is)

like image 135
Günter Zöchbauer Avatar answered Oct 31 '22 21:10

Günter Zöchbauer


The this corresponds to the instance of your component within the event handler (canvasKeyHandler). I think that using the following to configure the handler for the keydown event is enough:

(keydown)="canvasKeyHandler($event)"

I saw that you initialize the dolly property within the init method. But I can't see where this method is called. Perhaps it's the reason of your problem...

like image 24
Thierry Templier Avatar answered Oct 31 '22 19:10

Thierry Templier