angular 2 reference to another *.ts component

I’m trying to extend Angular 2 Hero Example to ag-grid SampleAppComponent. I created CarDetailComponent with @input that allow me edit car price. Modified car price value is bound to and changes are reflected on RowData of the grid, but in order it to be reflected on the grid, there should be explicit refresh call on the grid. This call I included when user clicks a row another time. Then you see new value for price in grid.
Now i want that refresh grid call to happen from within “onKey” function of CarDetailComponent @input. My problem is i can’t reference from CarDetailComponent the instance of SampleAppComponent. I tried constructor with SampleAppComponent as param, but got “circular reference error”. @Autowired didn’t work either: prop sampleAppComponent remaines undefined. Any clue provided would a great help. Below’s the code.
car-detail.component.ts:

 import {Component, Input} from 'angular2/core';
    import {Car} from './car';
    import {SampleAppComponent} from './SampleAppComponent';

    import {Bean} from 'ag-grid/main';
    import {Autowired} from 'ag-grid/main';



    @Component({
      selector: 'my-car-detail',
      template: `
        <div *ngIf="car">
          <h2>{{car.make}} details</h2>
          <div>
            <label>Model: </label>{{car.model}};
            <label> Year: </label>{{car.year}}
          </div>
          <div>
            <label>Price: </label>
            <input [(ngModel)]="car.price" placeholder="price" (keyup)="onKey($event)"/>
          </div>
        </div>
      `,

    })

    @Bean('CarDetailComponent')
    export class CarDetailComponent {
      @Autowired('sampleAppComponent') private sampleAppComponent: SampleAppComponent;

          @Input() car: Car;

           onKey(event:KeyboardEvent) {
            console.log((<HTMLInputElement>event.target).value) ;
            this.sampleAppComponent.gridOptions.api.refreshView(); // this.sampleAppComponent is undefined !!!
          }
        }

    **SampleAppComponent.ts**
import {Component} from 'angular2/core';
import {AgGridNg2} from 'ag-grid-ng2/main';
import {GridOptions} from 'ag-grid/main';
import {GridOptionsWrapper} from 'ag-grid/main';
import {GridApi} from 'ag-grid/main';
import {Car} from './car';
import {CarService} from './car.service';
import {CarDetailComponent} from './car-detail.component';
import 'ag-grid-enterprise/main';
import {Utils as _} from 'ag-grid/main';

import {Bean} from 'ag-grid/main';

import {PostConstruct} from "ag-grid/main";

var carService: CarService;

console.log("Component start");
@Component({
    selector: 'app',
    template: `<ag-grid-ng2 
               class="ag-fresh" style="height: 300px"  
               [columnDefs]="columnDefs" 
               [rowData] = "rowData"
               [enableColResize]="true"
               [singleClickEdit]="true"
               [enableSorting]="true"
               [enableRangeSelection]="true"
               (rowClicked)="onRowClicked($event)"
               (cellValueChanged)="onKey($event)"
               [gridOptions]="gridOptions"
               >
               </ag-grid-ng2>
               <ul class="cars">
                 <li *ngFor="#car of cars"
                   [class.selected]="car === selectedCar"
                   (click)="onSelect(car)">
                   <span class="badge">{{car.make}}</span> {{car.price}}
                 </li>
               </ul>
               <my-car-detail [car]="selectedCar"></my-car-detail>   
              `,

    directives: [AgGridNg2, CarDetailComponent],
    providers: [CarService]
})

@Bean('SampleAppComponent')
export class SampleAppComponent {
   public gridOptions: GridOptions;

    private rowData: Object[];
    selectedCar: Car;
    private eRoot: HTMLElement;
    private api: GridApi;

     onRowClicked(event: Event) {
        var currentRow: Car;
        currentRow = <Car> event.data;
        this.selectedCar = currentRow; 
        console.log('a row was clicked; row make: ' + currentRow.make + ', model: ' + currentRow.model + ', price: ' + currentRow.price + ", year: " + currentRow.year);  
        this.gridOptions.api.refreshView(); 

    }

    onKey(event:KeyboardEvent){
       console.log("onKey Output: " + (<HTMLInputElement>event.target).value);
       this.gridOptions.api.refreshView();
    }

    constructor(private _carService: CarService) {
     console.log("in Grid constructor...");   
     carService = this._carService;

     this._carService.getCars().then(CARS => this.rowData = CARS);




    this.gridOptions = {
        enableSorting: true,
        rowData: this.rowData,
        onReady: () => {
            this.gridOptions.api.sizeColumnsToFit();
            alert(this.gridOptions.api);
        }
     }



   };


    @PostConstruct
    public init(): void {
         console.log("in Grid POST constructor..."); 
    }

   columnDefs = [
        { headerName: "Make", field: "make" },
        { headerName: "Model", field: "model" },
        {
            headerName: "Price",
            field: "price",
            cellClass: 'rightJustify',
            cellRenderer: function (params: any) {
                return '$' + params.value.toString().replace(/B(?=(d{3})+(?!d))/g, ","); //thanks http://stackoverflow.com/users/28324/elias-zamaria
            }
        },
        { headerName: "Year", field: "year" },
    ];


onSelect(car: Car) { 
  this.selectedCar = car; 
  console.log('a car was selected; car: make: ' + car.make + ', model: ' + car.model + ', price: ' + car.price + ", year: " + car.year);   
 };
}

1
Leave a Reply

avatar
1 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
Jason Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
Jason
Guest

I would define an @Ouput in you car details component:

export class CarDetailComponent {
  (...)
  @Input() car: Car;

  @Output() updated:EventEmitter = new EventEmitter();
  (...)

  onKey(event:KeyboardEvent) {
     console.log((<HTMLInputElement>event.target).value) ;
     this.updated.emit();
  }
}

In the template of the SampleAppComponent component you can subscribe on this event:

<my-car-detail (updated)="refreshGrid()" [car]="selectedCar"></my-car-detail>

to refresh the grid:

@Component({ ... })
export class SampleAppComponent {
  (...)
  refreshGrid() {
    this.gridOptions.api.refreshView();
  }
}