类变量仅在一种特定方法中未定义

时间:2019-08-20 08:58:52

标签: angular

我正在将Chessboardjs和Chessjs这两个著名的Chess javascript库包装到Angular项目中。除了我的组件.ts中的一个方法外,其他一切都运行良好。当拖动一块(在config中定义)并且外部调用成功时,外部js库会调用此方法。 我的问题是,在此方法“ onDragStart()”中,即使我在ngOnInit()中初始化并使用它们,也无法使用类变量board和game,因为它们似乎是未定义的。即使对updateStatus()的调用也被拒绝,好像此方法看不到类的任何一位。这是我组件的代码:

declare var ChessBoard: any;
declare var Chess: any;

@Component( {
    selector: 'app-chessboard',
    templateUrl: './chessboard.component.html',
    styleUrls: ['./chessboard.component.css']
} )
export class ChessboardComponent implements OnInit {

    board: any;
    game: any;

    constructor() { }


    ngOnInit() {
        var config = {
            orientation: 'white',
            draggable: true,
            position: 'start',
            moveSpeed: 'fast',
            snapbackSpeed: 100,
            snapSpeed: 100,
            pieceTheme: 'img/chesspieces/wikipedia/{piece}.png',
            showNotation: false,
            onDragStart: this.onDragStart,
        }

        this.board = new ChessBoard( 'board', config )

        this.game = new Chess();

        console.log('color of g5: ' + this.game.square_color('g5'));

        this.board.move('e2-e4');

        this.updateStatus();

    }


    onDragStart (source, piece, position, orientation) {
        // do not pick up pieces if the game is over
        if (this.game.game_over()) {return false};

        // only pick up pieces for the side to move
        if ((this.game.turn() === 'w' && piece.search(/^b/) !== -1) ||
            (this.game.turn() === 'b' && piece.search(/^w/) !== -1)) {
          return false
        };
        return true;
      }


    updateStatus () {
        var status = ''

        var moveColor = 'White'
        if (this.game.turn() === 'b') {
          moveColor = 'Black'
        }

        // checkmate?
        if (this.game.in_checkmate()) {
          status = 'Game over, ' + moveColor + ' is in checkmate.'
        }

        // draw?
        else if (this.game.in_draw()) {
          status = 'Game over, drawn position'
        }

        // game still on
        else {
          status = moveColor + ' to move'

          // check?
          if (this.game.in_check()) {
            status += ', ' + moveColor + ' is in check'
          }
        }

        console.log(status);
      }

}
```

and the error message I get when I try to drag a piece:

core.js:6014 ERROR TypeError: Cannot read property 'game_over' of undefined
    at Object.onDragStart (chessboard.component.ts:46)
    at I (chessboard-1.0.0.min.js:2)
    at HTMLDivElement.D (chessboard-1.0.0.min.js:2)
    at HTMLDivElement.dispatch (jquery.min.js:2)
    at HTMLDivElement.v.handle (jquery.min.js:2)
    at ZoneDelegate.invokeTask (zone-evergreen.js:391)
    at Object.onInvokeTask (core.js:39679)
    at ZoneDelegate.invokeTask (zone-evergreen.js:390)
    at Zone.runTask (zone-evergreen.js:168)
    at ZoneTask.invokeTask [as invoke] (zone-evergreen.js:465)

In this case is 'game' being undefined but I get the same result if I try to use 'board'.
The call to the method is correct: source, piece, position, orientation are filled with good values.
Any Idea? I just don't understand it...

Thanks a lot!

Paolo

1 个答案:

答案 0 :(得分:0)

我终于设法找到一个解决方案,这是一个上下文问题。

该JS库通过该行链接到一个回调函数

onDragStart:this.onDragStart

但是这导致要使用的组件的新实例,因此所有内容都未定义。

实现回调的正确方法是:

onDragStart:this.onDragStart.bind(this),

一切都很好:)