在作为Angular 2中的方法传递的事件侦听器回调中,对象未定义

时间:2018-06-02 08:23:07

标签: angular typescript

我是角度2和打字稿的新手,在我的项目中,我已动态创建表格并附加到棋盘DIV。我已经将addEventLister赋予表并将回调作为方法传递。但是每当触发一个事件时,对象(下面代码中的this.diamondSet)都给出了undefined。我无法找到我做错的事情

请帮助我找到错误,提前致谢,

app.component.ts



import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
  board_row: number = 8;
  board_col: number = 8;
  cellNum: number = 0;
  cellCordinates: Object = {};
  diamond_count: number = 8;
  diamondSet: Object = {};
  winCount: number = 0;

  ngOnInit() {
  	this.randomGenerators();
    this.initializeBoard();
    }

    initializeBoard() {
    let table = document.createElement("table");
    table.id = "diamond_container";
    for (let i = 0; i < this.board_row; i++) {
        let tr = document.createElement('tr');
        for (let j = 0; j < this.board_col; j++) {
            let td = document.createElement('td');
            this.cellCordinates[this.cellNum] = {
                x: i,
                y: j
            };
            td.className = "cell unknown";
            td.id = `${this.cellNum}`;
            this.cellNum++;
            tr.appendChild(td);
        }
        table.appendChild(tr);
    }
    document.getElementById("board").appendChild(table);
    document.getElementById("diamond_container").addEventListener("click", this.clickHandler);
}
randomGenerators() {
    while (Object.keys(this.diamondSet).length < this.diamond_count) {
        let randomnumber = Math.ceil(Math.random() * 63)
        this.diamondSet[randomnumber] = randomnumber;
    }
}
clickHandler(e) {
	console.log("handru");
	if (Object.keys(this.diamondSet).length) {
        if (e.target.nodeName == 'TD') {
            this.winCount++;
            console.log("before")
            if (this.diamondSet[e.target.id]) {
                e.target.className = "cell diamond disabled";
                delete this.diamondSet[e.target.id];
               
            } else {
                var slope = this.hint(e.target.id);
                $('td').removeClass('arrow');
                e.target.className = "cell arrow disabled";
                e.target.style["boxShadow"] = 'none';
                e.target.style["transform"] = "rotate(" + slope + "deg)";
            }
        }
    }	
}

minDistance(clicked_id) {
    var distanceMap = {};
    Object.keys(this.diamondSet).map((id) => {
        distanceMap[id] = Math.abs(this.cellCordinates[clicked_id].x - this.cellCordinates[id].x) + Math.abs(this.cellCordinates[clicked_id].y - this.cellCordinates[id].y);
    });
    return Object.keys(distanceMap).sort(function(a, b) {
        return distanceMap[a] - distanceMap[b]
    })[0];
}

hint(clicked_id) {
    let nearestDiamondId = this.minDistance(clicked_id);
    return (Math.atan2((this.cellCordinates[nearestDiamondId].x - this.cellCordinates[clicked_id].x), (this.cellCordinates[nearestDiamondId].y - this.cellCordinates[clicked_id].y))) * 180 / Math.PI;
}
}
&#13;
&#13;
&#13;

app.component.html

&#13;
&#13;
<div class="container" id="container">
  <center>
    <h1>
      Diamond Sweeper
    </h1>
  </center>
  <div class="row">
    <div class="col-xs-12" id="board">
    </div>
  </div>
</div>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

当您使用.addEventListener()添加eventListener时,此上下文是Element本身,而不是您的组件。

您可以使用箭头功能轻松解决此问题:

clickHandler = (e) => {
    ... // your function code here
}

答案 1 :(得分:0)

另一种方法是将非箭头功能与您的组件绑定。

clickHandlerUnbinded(e)  {
   ... // your function code here
}

clickHandler = this.clickHandlerUnbinded.bind(this); // this -> is your component

document.getElementById("diamond_container").addEventListener("click", this.clickHandler);

现在您有了一个clickHandler上下文,该上下文的this绑定到了您的组件。

使用箭头功能显然更加优雅。