2017-04-24 1 views
2

J'ai un problème lorsque je souhaite utiliser une méthode d'un composant angulaire2. Voici le code:Impossible de lire la propriété angulaire2 non définie

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); 
} 
} 

Et voici l'erreur que je reçois:

EXCEPTION: Cannot read property 'goToDetail' of undefined 

Je ne comprends pas vraiment ce qui se passe ici ... Est-ce en raison de l'appel de la souscription méthode ?

+0

Il est probable que cette ligne 'this.goToDetail (event.data.uuid);'. Déboguer et voir quelles valeurs sont dans event.data.uuid, je suppose qu'elles sont nulles ou pas une chaîne – jhhoff02

+0

J'ai ajouté cette ligne juste avant l'appel: 'console.log (event.data.uuid);' Je reçois la chaîne de droite sur l'écran et également le même message que ci-dessus comme une erreur – eli0T

+0

Faites un console.log sur ce que le message d'erreur indique qu'il ne peut pas lire la propriété goToDetail. –

Répondre

2

Avez-vous essayé d'utiliser la méthode Function.prototype.bind(), qui vous permet de spécifier la valeur qui doit être utilisée comme this lorsque le rappel est déclenché?

Comme ceci:

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

Si vous ne spécifiez pas quelle valeur doit être utilisée comme this, la valeur de this à l'intérieur du gestionnaire est une référence à l'élément (et, par conséquent, non définie).

+0

Merci beaucoup! 'this.gridOptions.api.addEventListener ('rowClicked', this.myRowClickedHandler.bind (this));' a résolu le problème! – eli0T

2

Ce qui se passe ici est que lorsque votre événement rowClicked est déclenché, this dans this.goToDetail(event.data.uuid); n'est pas exécuté à partir de l'appel site, vous pourriez penser qu'il est exécuté à partir. Comme vous l'avez écrit, vous pourriez penser que c'est call-site est AllComponent classe, mais ce n'est vraiment pas, c'est l'endroit où votre écouteur d'événements est appelé, et dans l'exécution, this ne se réfère pas à votre classe.

réponse de Tobold est une solution, mais vous pouvez l'essayer avec « gras flèche » ainsi:

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

Ici, votre fonction myRowClickedHandler sera toujours correcte « ce ».

+0

Oui, cela fonctionnerait aussi. Lors de l'utilisation des fonctions de la flèche grasse, la valeur de la variable 'this' est déterminée par la portée environnante. – Tobold