Passing value between two components (pages) in Angular 2

后端 未结 2 2034
面向向阳花
面向向阳花 2020-12-16 19:41

I am using Angular 2 (TypeScript)

I have two components (actually they are two pages too). They are NOT parent and child relationship.

I want to pass a value

相关标签:
2条回答
  • 2020-12-16 20:16

    The canonical way is to establish an injectable service and inject the service into any components that need the data. Since the service is a singleton, the components will be accessing the same data. It shouldn't matter that they are on different pages. Plunker here.

    Edit: Here's a more involved example that shows two-way communication between components by subscribing to an eventEmitter on a service: Plunker

    import {Component, Injectable} from 'angular2/core'
    
    // your shared service 
    // provide reference in parent component or bootstrap 
    @Injectable()
    export class myService {
      sharedData:string = "String from myService"
    }
    
    @Component({
      selector: 'page1',
      providers: [],
      template: `
        <div>
          <b>Component Page1 - shared data:</b> {{SharedData}}
        </div>
      `,
      directives: [],
    })
    export class Page1 {
      constructor(aService: myService) {
        this.SharedData = aService.sharedData
      }
    }
    
    @Component({
      selector: 'page2',
      providers: [],
      template: `
        <div>
          <b>Component Page2 - shared data:</b> {{SharedData}}
        </div>
      `,
      directives: [],
    })
    export class Page2 {
      constructor(aService: myService) {
        this.SharedData = aService.sharedData
      }
    }
    
    0 讨论(0)
  • 2020-12-16 20:20

    Thank you MarkM! It works, but it has been difficult for me because I have it all in diferent files and over last angular2 using angular cli... So I explain it here:

    First of all: You need to create a file with the class you want to share with other components: data.service.ts and make it "@Injectable":

    import { Injectable } from '@angular/core';
    
    @Injectable()
    export class myService {
      public sharedData:string;
    
      constructor(){
        this.sharedData = "String from myService";
      }
    
      setData (data) {
        this.sharedData = data;
      }
      getData () {
        return this.sharedData;
      }
    }
    

    Make sure you set the created class (myService) on 'providers' only once on the app.module.ts file and import the injectable file: data.service.ts:

    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { routing, appRoutingProviders } from './app.routing';
    import { AppComponent } from './app.component';
    import { AppContent } from './components/content.component';
    import { AppInsertContent } from './components/insert.component';
    import { myService } from './services/data.service';
    
    @NgModule({
      declarations: [
        AppComponent,
        AppContent,
        AppInsertContent,
      ],
      imports: [
        BrowserModule,
        routing
      ],
      providers: [appRoutingProviders, myService],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    

    Wherever you want to use your shared class use the constructor to create an object from the class (this object will be unique for your components, thanks to the @Injectable decorator). Remember to import it on every file you use it!...

    In my case this view sets the data of the object with a text input: input.component.ts

    import { Component } from '@angular/core';
    import { myService } from '../services/data.service';
    
    @Component({
      selector: 'insert-content',
      template: `
       <input id="textbox" #textbox type="text">
       <button (click)="this._myService.setData(textbox.value); SharedData = textbox.value;">SAVE</button>
       Object data: {{SharedData}}
    
        <div class="full-button">
          <a routerLink="/" routerLinkActive="active">BACK</a>
        </div>
      `
    })
    
    export class AppInsertContent {
      SharedData: string;
      constructor (private _myService: myService){
        console.log(this._myService.getData());
      }
    }
    

    And in this view I just see the data that has been set on the object: content.component.ts

    import { Component } from '@angular/core';
    import { myService } from '../services/data.service';
    
    @Component({
      selector: 'app-content',
      template: `
      <div style="float:left; clear:both;"> 
        {{_myService.getData()}} 
      </div>
    
      <div class="full-button">
        <a routerLink="/insert" routerLinkActive="active">INSERT</a>
      </div>
      `
    })
    export class AppContent {
      constructor (private _myService: myService){
        console.log(this._myService.getData());
      }
    }
    

    I hope this info is usefull!

    0 讨论(0)
提交回复
热议问题