2017-04-24 111 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