如何在Angular 2中将对象从一个组件传递到另一个组件?

时间:2015-12-04 12:15:21

标签: angular angular2-directives

我有 Angular组件,第一个组件使用第二个组件作为指令。 它们应该共享相同的模型对象,它在第一个组件中初始化。 如何将该模型传递给第二个组件?

5 个答案:

答案 0 :(得分:56)

对于从父级到子级的单向数据绑定,使用@Input装饰器(样式指南为recommended)指定子组件的输入属性

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

并在父模板中使用模板属性绑定

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

由于传递对象(JavaScript引用类型),因此对父组件或子组件中的对象属性所做的任何更改都将反映在另一个组件中,因为两个组件都引用了同一对象。我在Plunker中显示了这个。

如果您在父组件中重新分配对象

this.model = someNewModel;

Angular会将新对象引用传播到子组件(作为更改检测的一部分自动传播)。

您唯一不应该做的是重新分配子组件中的对象。如果这样做,父级仍将引用原始对象。 (如果确实需要双向数据绑定,请参阅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

答案 1 :(得分:19)

组件2,指令组件可以在Typescript中定义输入属性(@input注释)。组件1可以将该属性从模板传递给指令组件。

请参阅此SO回答How to do inter communication between a master and detail component in Angular2?

以及如何将输入传递给子组件。在你的情况下,它是指令。

答案 2 :(得分:13)

您还可以将数据存储在带有setter的服务中并通过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;
    }
}

答案 3 :(得分:2)

使用输出注释

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

答案 4 :(得分:0)

来自组件

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
}

到组件

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
    }

}