2017-04-24 114 views
2

我想要使用angular2组件的方法时遇到问题。 下面的代码:无法读取undefined 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 

我真的不明白这里发生了什么...... 这是由于从订阅电话方法 ?

+0

这可能是this.goToDetail(event.data.uuid);'。调试,看看在event.data.uuid什么值,我猜他们是空的或不是一个字符串 – jhhoff02

+0

我刚刚添加此行在调用之前: 'console.log(event.data.uuid);' 我得到在屏幕上的正确的字符串,也是上述相同的消息作为错误 – eli0T

+0

对此做一个console.log作为错误消息说,它不能读取属性goToDetail。 –

回答

2

您是否尝试过使用Function.prototype.bind()方法,它可以让你指定回调触发时应作为this价值?

像这样:

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

如果不指定值应作为this,的this处理程序内的值是将元件(因此,未定义)的引用。

+0

非常感谢! 'this.gridOptions.api.addEventListener('rowClicked',this.myRowClickedHandler.bind(this));' 解决了这个问题! – eli0T

2

这里发生的事情是,当被触发你的rowClicked事件,thisthis.goToDetail(event.data.uuid);不是从你可能会认为它是从执行调用点执行。你可能会认为它的调用方式是AllComponent类,但它确实不是,它是你的事件监听器被调用的地方,在执行时,this没有引用你的类。

Tobold的回答是一个解决方案,但你可以用“胖箭头”,以及尝试一下:

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

在这里,您myRowClickedHandler函数总是有正确的“本”。

+0

是的,这也可以。当使用胖箭头功能时,变量'this'的值由周围的范围决定。 – Tobold