web-dev-qa-db-fra.com

Comment passer un objet d'un composant à un autre dans Angular 2?

J'ai des composants angulaires et le premier composant utilise le second comme directive . Ils doivent partager le même modèle objet, qui est initialisé dans le premier composant. Comment puis-je passer ce modèle à la deuxième composante?

54
Anoush Hakobyan

Composant 2, le composant directive peut définir une propriété d'entrée (annotation @input dans TypeScript). Et le composant 1 peut transmettre cette propriété au composant directive du modèle.

Voir ceci SO answer Comment faire la communication entre un composant maître et un composant de détail dans Angular2?

et comment l'entrée est transmise aux composants enfants. Dans votre cas, c'est directive.

19
Chandermani

Pour une liaison de données unidirectionnelle de parent à enfant, utilisez le décorateur @Input (en tant que recommandé par le guide de style) pour spécifier une propriété d'entrée sur le composant enfant.

@Input() model: any;   // instead of any, specify your type

et utiliser la liaison de propriété de modèle dans le modèle parent

<child [model]="parentModel"></child>

Puisque vous transmettez un objet (un type de référence JavaScript), toute modification apportée aux propriétés de l'objet dans le composant parent ou enfant sera reflétée dans l'autre composant, car les deux composants font référence au même objet. Je montre cela dans le Plunker .

Si vous réaffectez l'objet dans le composant parent

this.model = someNewModel;

Angular propage la nouvelle référence d'objet au composant enfant (automatiquement, dans le cadre de la détection des modifications).

La seule chose à ne pas faire est de réaffecter l'objet dans le composant enfant. Si vous faites cela, le parent référencera toujours l'objet d'origine. (Si vous avez besoin d'une liaison de données bidirectionnelle, voir https://stackoverflow.com/a/34616530/215945 ).

@Component({
  selector: 'child',
  template: `<h3>child</h3> 
    <div>{{model.prop1}}</div>
    <button (click)="updateModel()">update model</button>`
})
class Child {
  @Input() model: any;   // instead of any, specify your type
  updateModel() {
    this.model.prop1 += ' child';
  }
}

@Component({
  selector: 'my-app',
  directives: [Child],
  template: `
    <h3>Parent</h3>
    <div>{{parentModel.prop1}}</div>
    <button (click)="updateModel()">update model</button>
    <child [model]="parentModel"></child>`
})
export class AppComponent {
  parentModel = { prop1: '1st prop', prop2: '2nd prop' };
  constructor() {}
  updateModel() { this.parentModel.prop1 += ' parent'; }
}

Plunker - Angular RC.2

57
Mark Rajcok

vous pouvez également stocker vos données dans un service avec un setter et l'obtenir via un getter

import { Injectable } from '@angular/core';

@Injectable()
export class StorageService {

    public scope: Array<any> | boolean = false;

    constructor() {
    }

    public getScope(): Array<any> | boolean {
        return this.scope;
    }

    public setScope(scope: any): void {
        this.scope = scope;
    }
}
13
ueman

Utiliser l'annotation de sortie

@Directive({
  selector: 'interval-dir',
})
class IntervalDir {
  @Output() everySecond = new EventEmitter();
  @Output('everyFiveSeconds') five5Secs = new EventEmitter();
  constructor() {
    setInterval(() => this.everySecond.emit("event"), 1000);
    setInterval(() => this.five5Secs.emit("event"), 5000);
  }
}
@Component({
  selector: 'app',
  template: `
    <interval-dir (everySecond)="everySecond()" (everyFiveSeconds)="everyFiveSeconds()">
    </interval-dir>
  `,
  directives: [IntervalDir]
})
class App {
  everySecond() { console.log('second'); }
  everyFiveSeconds() { console.log('five seconds'); }
}
bootstrap(App);
2
E. Fortes

À partir de composant

import { Component, OnInit, ViewChild} from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import { dataService } from "src/app/service/data.service";
    @Component( {
        selector: 'app-sideWidget',
        templateUrl: './sideWidget.html',
        styleUrls: ['./linked-widget.component.css']
    } )
    export class sideWidget{
    TableColumnNames: object[];
    SelectedtableName: string = "patient";
    constructor( private LWTableColumnNames: dataService ) { 
       
    }
    
    ngOnInit() {
        this.http.post( 'getColumns', this.SelectedtableName )
            .subscribe(
            ( data: object[] ) => {
                this.TableColumnNames = data;
     this.LWTableColumnNames.refLWTableColumnNames = this.TableColumnNames; //this line of code will pass the value through data service
            } );
    
    }    
    }

DataService

import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';

@Injectable()
export class dataService {
    refLWTableColumnNames: object;//creating an object for the data
}

À composant

import { Component, OnInit } from '@angular/core';
import { dataService } from "src/app/service/data.service";

@Component( {
    selector: 'app-linked-widget',
    templateUrl: './linked-widget.component.html',
    styleUrls: ['./linked-widget.component.css']
} )
export class LinkedWidgetComponent implements OnInit {

    constructor(private LWTableColumnNames: dataService) { }

    ngOnInit() {
    console.log(this.LWTableColumnNames.refLWTableColumnNames);
    }
    createTable(){
        console.log(this.LWTableColumnNames.refLWTableColumnNames);// calling the object from another component
    }

}
0
Shafeeq Mohammed