无法读取未定义的属性angular2。

3

我想使用一个angular2组件的方法时遇到了问题,以下是代码:

import { Component,OnInit } from '@angular/core';
import { Router } from '@angular/router';
import {AgGridModule} from 'ag-grid-angular/main';
import {GridOptions, GridApi, ColumnApi} from "ag-grid";

import { AllService } from './all.service';
import { SomeClass } from './someClass';
import { ResponseData, Links } from './response';

import 'rxjs/Rx';

@Component({
  selector: 'all',
  styleUrls: ['./all.scss'],
  templateUrl: './all.html'
})

export class AllComponent implements OnInit {

embedded: Array<SomeClass>
page: number;
page_count: number;
link: Array<Links> = [];
total_items: number;
page_size: number;
private gridOptions: GridOptions = {
    enableFilter: true,
    enableSorting: true,
    //pagination: true,
    enableColResize: true,
    animateRows: true
};
private api: GridApi;
private columnApi: ColumnApi;
private json : JSON;
private test : String;
private n : number = 0;

constructor (private service: AllService, private router: Router) {

}

ngOnInit(){
    this.getData();
}

private myRowClickedHandler(event) {
    this.goToDetail(event.data.uuid);
}

private getData(){
  this.service.getInitData().subscribe(data => {  this.embedded = data._embedded.some_class;
                                                    this.page = data.page;
                                                    this.page_count = data.page_count;
                                                    this.page_size = data.page_size;
                                                    this.total_items = data.total_items;
                                                    this.link[0] = data._links;
                                                    this.createGrid();

                                                    this.gridOptions.api.addEventListener('rowClicked', this.myRowClickedHandler);
                                                });
}

private createGrid(){
    this.n = this.embedded.length;
    this.gridOptions.columnApi.autoSizeColumns;
    this.gridOptions.api.setColumnDefs(this.createColumnDefs());
    this.gridOptions.api.setRowData(this.createRows());
    this.gridOptions.api.sizeColumnsToFit();
}

private createRows(){

    var rowData:any[] = [];

    var regexp1 = /[a-zA-Z0-9]*$/;

    for (var i = 0; i < this.n; i++) {

        rowData.push({
            uuid: this.embedded[i].uuid,
            state: this.embedded[i].state,
            executionDate: this.embedded[i].executionDate,
            startDate: this.embedded[i].startDate,
            endDate: this.embedded[i].endDate,
            taskClass: regexp1.exec(this.embedded[i].taskClass)[0],
            humanDuration: this.embedded[i].humanDuration,
            humanMemoryConsumption: this.embedded[i].humanMemoryConsumption,
        });
    }

    return rowData;

}

private createColumnDefs() {
    return [
      {headerName: 'uuid', field: 'uuid'},
      {headerName: 'state', field: 'state', filter: 'text', cellStyle: function(params) {
          switch(params.value){
              case "STATE1": return {color: 'orange'};
              case "STATE23": return {color: 'green'};
              case "STATE8": return {color: 'red'};
          }
      }},
      {headerName: 'executionDate', field: 'executionDate'},
      {headerName: 'startDate', field: 'startDate'},
      {headerName: 'endDate', field: 'endDate'},
      {headerName: 'taskClass', field: 'taskClass'},
      {headerName: 'humanDuration', field: 'humanDuration'},
      {headerName: 'humanMemoryConsumption', field: 'humanMemoryConsumption'},
      {headerName: 'action', field: 'action'}
    ]
}

public goToDetail(uuid: String) {
    let link = ['pages/all', uuid];
    this.router.navigate(link);
}
 }

这是我收到的错误信息:


EXCEPTION: Cannot read property 'goToDetail' of undefined

我真的不太明白这里正在发生什么...... 这是由subscribe方法的调用引起的吗?

很有可能是这一行 this.goToDetail(event.data.uuid);。调试一下,看看 event.data.uuid 中的值是什么,我猜它们可能为 null 或者不是字符串类型。 - jhhoff02
我在调用前添加了这行代码: console.log(event.data.uuid); 我在屏幕上得到了正确的字符串,同时也收到了与上述相同的错误消息。 - eli0T
请在控制台上使用console.log,因为错误消息显示无法读取goToDetail属性。 - Stephen Wilson
我遇到了一个“未定义”的错误,但是我无法弄清楚原因。 - eli0T
1
谢谢您提供的链接!我确实完全误解了这个关键字... - eli0T
2个回答

3

您尝试过使用Function.prototype.bind()方法吗?该方法允许您在触发回调时指定应用作this的值。

像这样:

this.gridOptions.api.addEventListener('rowClicked', this.myRowClickedHandler.bind(this), false);

如果您没有指定哪个值应该被用作this,则处理程序内部的this引用元素(因此为undefined)。


1
非常感谢! this.gridOptions.api.addEventListener('rowClicked', this.myRowClickedHandler.bind(this)); 问题已解决! - eli0T

2
这里发生的情况是:当触发rowClicked事件时,this.goToDetail(event.data.uuid)中的this并非从你所认为的调用站点执行。你可能认为它的调用站点是AllComponent类,但实际上并不是,它是在事件监听器被调用的地方,并且在执行时,this不指向你的类。
Tobold的答案是一种解决方法,但你也可以尝试使用“fat arrow”(即箭头函数)来达到相同的效果。
private myRowClickedHandler = (event) => {
    this.goToDetail(event.data.uuid);
}

在这里,你的myRowClickedHandler函数将始终具有正确的“this”。


是的,这也可以工作。使用箭头函数时,变量this的值由周围的作用域确定。 - Tobias

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接