code16
code16

Reputation: 41

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

Upvotes: 1

Views: 805

Answers (1)

Thierry Templier
Thierry Templier

Reputation: 202176

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

Upvotes: 0

Related Questions