【问题标题】:Angular pass array to another (NOT child) component角度传递数组到另一个(非子)组件
【发布时间】:2020-08-01 04:17:39
【问题描述】:

我对 Angular 相当陌生,并且无法将数组传递给不同的(与父/子无关的)组件。我想要在我的应用程序中单击一个按钮以将其标记为“已接受”,并以不同的路线在不同的视图(接受的数组视图)中显示相同的数组。我已经尝试使用@Input 和共享服务来完成此操作,但它就是行不通。你能指出我正确的方向吗?谢谢。

sharedService.ts //My array is called 'Turno'

    import {Injectable} from '@angular/core';
    import {Turno} from '../models/turno';


    @Injectable()

    export class SharedService{


    public turno:Turno;


        constructor(){

        }



setArray(turno){
    this.turno=turno;
}
getArray(){

    return this.turno;
}
}

第一个组件(我用 accept() 方法标记了一个接受的数组):

@Component({
  selector: 'app-turnos',
  templateUrl: './turnos.component.html',
  styleUrls: ['./turnos.component.css'],
  providers:[TurnoService, SharedService]
})
export class TurnosComponent implements OnInit {

    public turnos: Turno;
    public status;


  constructor(

    private _turnoService: TurnoService,
    private _sharedService: SharedService

    ) { }

  ngOnInit(): void {

    this._turnoService.getTurnos().subscribe(
        response=>{
            if(response.status== 'success'){
                this.turnos= response.turnos;
                this.status=response.status;
                console.log(this.turnos);
            }else{
                this.status= 'error';
            }

        },error=>{
            console.log('error');
        }

        );

  }

  accept(turno){

    this._sharedService.setArray(turno);
    console.log(turno);


  }

第二个组件(接收并列出接受的数组)

import { Component, OnInit} from '@angular/core';
import {SharedService} from '../../services/shared.service';
import {Turno} from '../../models/turno';

@Component({
  selector: 'app-turnoaceptado',
  templateUrl: './turnoaceptado.component.html',
  styleUrls: ['./turnoaceptado.component.css'],
  providers:[SharedService]
})
export class AcceptedTurnoComponent implements OnInit {

        public turnos: Turno;


  constructor(
    private _sharedService: SharedService

    ) { }


  ngOnInit(): void {
    this.turnos=this._sharedService.getArray();
    console.log(this.turnos);
  }



}

【问题讨论】:

  • 您能否向我们展示您尝试共享服务的代码?
  • 抱歉,已经完成了! :)

标签: arrays angular components sharing


【解决方案1】:

Angular中数据通信主要有三种方式。

    1. Using Input & Output for passing data to & from child component. 
       Also you can use ViewChild reference to access data (functions & 
       variables) of child component in parent component.
    2. A shared common service having setter & getter methods. 
       You can use it to set data. It acts as a temporary state.
    3. Using Browser storage in the form of session storage , local storage 
       or cookie. You can create one service which stores & takes in data 
       from browser storage & access it across components.

【讨论】:

    【解决方案2】:

    在这种情况下,共享服务是要走的路。

    每次添加新项目时发出数组的服务:

    import { Injectable } from '@angular/core';
    import { BehaviorSubject } from 'rxjs';
    
    @Injectable({
      providedIn: 'root',
    })
    export class ArrayServiceService {
      private acceptedArray = [];
      public acceptedArraySubject = BehaviorSubject<string[]>([]);
    
      addToAccepted(item: string) {
        this.acceptedArray.push(item);
        this.acceptedArraySubject.next(this.acceptedArray);
      }
    
      constructor() {}
    }
    
    

    调用该服务以添加项目的服务 (当然你从哪里得到你的项目取决于你,我相信你知道如何通过点击事件传递一个项目,所以我没有显示 html):

    import { Component, OnInit } from '@angular/core';
    import { ArrayService } from '../array.service';
    
    @Component({
      selector: 'app-first-component',
      templateUrl: './first-component.component.html',
      styleUrls: ['./first-component.component.scss'],
    })
    export class FirstComponentComponent implements OnInit {
    
      private allItemsArray = ['item1', 'item2', 'item3'];
    
      markAsAccepted(item: string) {
        this.arrayService.addToAccepted(item);
      }
    
      constructor(private arrayService: ArrayService) {}
    
      ngOnInit(): void {}
    }
    

    最后,第二个组件监听服务内部的变化并显示接受的数组:

    import { Component, OnInit } from '@angular/core';
    import { Observable } from 'rxjs';
    import { ArrayService } from '../array.service';
    import { share } from 'rxjs/operators';
    
    @Component({
      selector: 'app-second-component',
      templateUrl: './second-component.component.html',
      styleUrls: ['./second-component.component.scss'],
    })
    export class SecondComponentComponent implements OnInit {
      private acceptedArray: Observable<string[]>;
    
      constructor(private arrayService: ArrayService) {
        this.arrayService.acceptedArraySubject.pipe(share());
      }
    
      ngOnInit(): void {}
    }
    

    并在第二个组件的 html 中使用管道:

    <ul>
      <li *ngFor="let item of acceptedArray | async">{{item}}</li>
    </ul>
    

    我希望这能让你走上正轨。所以你有一个服务来保存你想要的数组,一个改变它的组件和另一个监听它的组件。但是你可以让很多组件监听它或改变它..

    【讨论】:

    • 谢谢!!你太棒了!,我不知道“行为主题”的东西,我会调查一下。非常感谢!,顺便说一句:你知道为什么我的 Getter 和 Setter 方法不起作用吗?
    • @Ayrton 不客气。在您的代码中,您设置了 Turno 对象,但在设置对象之后它什么也不做。所以你的共享服务持有新对象,没有人知道它。在第二个组件的 OnInit 函数中,共享服务中该对象的 getter 仅被调用一次。在 Initiation 之后它不再被调用。相反,当你监听一个 BehaviorSubject 时,每次调用 .necxt 时,它都会向所有监听它的观察者发出值。
    • 嗨 Cedric,我已经尝试了代码,但它不起作用,它需要一个 behaviorSuspect 的起始值,我将其声明为“未定义”,但每次我从第二个组件中获取数组时它显示为“未定义”。我找不到什么问题
    • @Ayrton 嗨,你能在 stackblitz 上发布一个例子吗?所以我可以看到问题出在哪里?对于 BehaviorSubject 而不是调用类型,您可以这样做: public acceptedArraySubject = new BehaviorSubject([]);
    猜你喜欢
    • 2019-08-03
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 2020-03-28
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多