Javascript Angular 4 在 2 个不相关的组件之间传递数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44414226/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 02:30:16  来源:igfitidea点击:

Angular 4 pass data between 2 not related components

javascriptangulartypescript

提问by User.Anonymous

I have a questions about passing data in Angular.

我有一个关于在 Angular 中传递数据的问题。

First, I don't have a structure as <parent><child [data]=parent.data></child></parent>

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

My structure is

我的结构是

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

So, in <summary />I have a select that do send value to <child-summary />and <content />.

所以,在<summary />我有一个选择发送值到<child-summary /><content />

OnSelect method is well fired with (change) inside <summary />component.

OnSelect 方法可以很好地使用(更改)内部<summary />组件。

So, I tried with @Input, @Outputand @EventEmitterdirectives, but I don't see how retrieve the event as @Input of the component, unless to go on parent/child pattern. All examples I've founded has a relation between component.

因此,我尝试使用@Input,@Output@EventEmitter指令,但我不知道如何将事件作为组件的 @Input 检索,除非继续使用父/子模式。我创建的所有示例都与组件之间存在关系。

EDIT : Example with BehaviorSubject not working (all connected service to API works well, only observable is fired at start but not when select has value changed)

编辑: BehaviorSubject 不起作用的示例(所有连接到 API 的服务运行良好,仅在启动时触发 observable,但在 select 值更改时不触发)

shared service = company.service.ts (used to retrieve company data)

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 (the "child")

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 (the trigerring "parent")

company.component.ts(触发“父”)

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

回答by JeffD23

This is a case where you want to use a shared service, as your components are structured as siblings and grandchildren. Here's an example from a video I created a video about sharing data between componentsthat solves this exact problem.

这是您想要使用共享服务的情况,因为您的组件被构造为兄弟姐妹和孙辈。这是一个视频示例,我创建了一个关于解决这个确切问题的组件之间共享数据的视频。

Start by creating a BehaviorSubject in the service

首先在服务中创建一个 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)
  }

}

Then inject this service into each component and subscribe to the 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)
  }

}

You can change the value from either component and the value will be updated, even if you don't have the parent/child relationship.

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

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

}

回答by Praneeth Reddy

There are two solutions for this.

对此有两种解决方案。

  1. This can be done through shared service by using observable's.

  2. You can use ngrx/store for this. This is similar to Redux arch. You will be getting data from state.

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

  2. 您可以为此使用 ngrx/store。这类似于 Redux arch。您将从州获取数据。

回答by Rohit Parte

Here is the simplest example of sharing data between two independent components, using event emitter and service

这是在两个独立组件之间共享数据的最简单示例,使用事件发射器和服务

https://stackoverflow.com/a/44858648/8300620

https://stackoverflow.com/a/44858648/8300620