首页 文章

角度4传递2个不相关组件之间的数据

提问于
浏览
19

我对在Angular中传递数据有疑问 .

首先,我没有 <parent><child [data]=parent.data></child></parent> 的结构

我的结构是

<container>
  <navbar>
    <summary></summary>
    <child-summary><child-summary>
  </navbar>
  <content></content>
</container>

所以,在 <summary /> 中,我有一个选择,它会向 <child-summary /><content /> 发送值 .

使用 <summary /> 组件内的(更改)可以很好地触发OnSelect方法 .

所以,我尝试了 @Input@Output@EventEmitter 指令,但我没有't see how retrieve the event as @Input of the component, unless to go on parent/child pattern. All examples I' ve创建了组件之间的关系 .

编辑:BehaviorSubject不工作的示例(API的所有连接服务都运行良好,只有在开始时才会触发observable,但是当select的值发生更改时不会触发)

shared service = company.service.ts(用于检索公司数据)

import { Injectable } from '@angular/core';
import { Headers, Http, Response } from '@angular/http';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/toPromise';

@Injectable()
export class SrvCompany {

    private accountsNumber = new BehaviorSubject<string[]>([]);
    currentAccountsNumber = this.accountsNumber.asObservable();

    changeMessage(accountsNumber: string[]) {
        this.accountsNumber.next(accountsNumber);
    }

    private _companyUrl = 'api/tiers/';

    constructor(private http: Http) { }

    getSociete(): Promise<Response> {
        let url = this._companyUrl;
        return this.http.get(url).toPromise();
    }
}

invoice.component.ts(“孩子”)

import { Component, OnInit, Input } from '@angular/core';
import { Headers, Http, Response } from '@angular/http';

import { SrvInvoice } from './invoice.service';
import { SrvCompany } from '../company/company.service';

@Component({
    selector: 'invoice',
    templateUrl: 'tsScripts/invoice/invoice.html',
    providers: [SrvInvoice, SrvCompany]
})

export class InvoiceComponent implements OnInit  {

    invoice: any;

    constructor(private srvInvoice: SrvInvoice, private srvCompany: SrvCompany)
    {

    }

    ngOnInit(): void {
        //this.getInvoice("F001");

        // Invoice data is linked to accounts number from company.
        this.srvCompany.currentAccountsNumber.subscribe(accountsNumber => {
            console.log(accountsNumber);
            if (accountsNumber.length > 0) {
                this.srvInvoice.getInvoice(accountsNumber).then(data => this.invoice = data.json());
            }
        });
    }

    //getInvoice(id: any) {
    //    this.srvInvoice.getInvoice(id).then(data => this.invoice = data.json());
    //}
}

company.component.ts(trigerring“parent”)

import { Component, Inject, OnInit, Input } from '@angular/core';
import { Headers, Http, Response } from '@angular/http';

import { SrvCompany } from './company.service';

@Component({
    selector: 'company',
    templateUrl: 'tsScripts/company/company.html',
    providers: [SrvCompany]    
})

export class CompanyComponent implements OnInit {

    societes: any[];    
    soc: Response[]; // debug purpose
    selectedSociete: any;

    ville: any;
    ref: any;
    cp: any;
    accountNumber: any[];

    constructor(private srvSociete: SrvCompany)
    {

    }

    ngOnInit(): void {
        this.getSocietes();
    }

    getSocietes(): void {

        this.srvSociete.getSociete()
            .then(data => this.societes = data.json())
            .then(data => this.selectItem(this.societes[0].Id));
    }

    selectItem(value: any) {
        this.selectedSociete = this.societes.filter((item: any) => item.Id === value)[0];
        this.cp = this.selectedSociete.CodePostal;
        this.ville = this.selectedSociete.Ville;
        this.ref = this.selectedSociete.Id;
        this.accountNumber = this.selectedSociete.Accounts;
        console.log(this.accountNumber);
        this.srvSociete.changeMessage(this.accountNumber);
    }
}

3 回答

  • 56

    在这种情况下,您希望使用共享服务,因为您的组件的结构是兄弟姐妹和孙子 . 以下是我创建了一个关于sharing data between components的视频的视频示例,该视频解决了这个问题 .

    首先在服务中创建一个BehaviorSubject

    import { Injectable } from '@angular/core';
    import { BehaviorSubject } from 'rxjs/BehaviorSubject';
    @Injectable()
    export class DataService {
    
      private messageSource = new BehaviorSubject("default message");
      currentMessage = this.messageSource.asObservable();
    
      constructor() { }
    
      changeMessage(message: string) {
        this.messageSource.next(message)
      }
    
    }
    

    然后将此服务注入每个组件并订阅observable .

    import { Component, OnInit } from '@angular/core';
    import { DataService } from "../data.service";
    @Component({
      selector: 'app-parent',
      template: `
        {{message}}
      `,
      styleUrls: ['./sibling.component.css']
    })
    export class ParentComponent implements OnInit {
    
      message:string;
    
      constructor(private data: DataService) { }
    
      ngOnInit() {
        this.data.currentMessage.subscribe(message => this.message = message)
      }
    
    }
    

    您可以更改任一组件的值,即使您没有父/子关系,也会更新该值 .

    import { Component, OnInit } from '@angular/core';
    import { DataService } from "../data.service";
    @Component({
      selector: 'app-sibling',
      template: `
        {{message}}
        <button (click)="newMessage()">New Message</button>
      `,
      styleUrls: ['./sibling.component.css']
    })
    export class SiblingComponent implements OnInit {
    
      message:string;
    
      constructor(private data: DataService) { }
    
      ngOnInit() {
        this.data.currentMessage.subscribe(message => this.message = message)
      }
    
      newMessage() {
        this.data.changeMessage("Hello from Sibling")
      }
    
    }
    
  • 0
  • 0

    有两种解决方案 .

    • 这可以通过使用observable来通过共享服务完成 .

    • 您可以使用ngrx / store进行此操作 . 这类似于Redux arch . 您将从州获取数据 .

相关问题