How to pass data to two level, three level down in Angular component, what's the best way to do it without props drilling?

huangapple go评论58阅读模式
英文:

How to pass data to two level, three level down in Angular component, what's the best way to do it without props drilling?

问题

我是新手使用Angular,我知道我们可以从高层次传递数据到低层次。就像在React中我们可以使用Context或Redux来避免props的传递。在Angular中是否也有类似的东西?

是的,我尝试过@Input和事件发射器,但我认为如果我们必须向下传递数据到第4层组件,这可能不是更好的选择。

英文:

I am new to Angular, I know we can pass data from top hierarchy to lower one. Like in React we can use Context or Redux to avoid props drilling. Do we have something similar in Angular also ?

Yes I did try @Input Event emitter But I don't think it would be better If we have to provide data to 4 level down component.

答案1

得分: 2

你可以使用服务。

// 服务
@Injectable({
providedIn: 'root'
})
export class SharedService {
private data$ = new BehaviorSubject(null);
get getData(): Observable {
return this.data$.asObservable();
}
set setData(value: DataInterface): void {
this.data$.next(value);
}
}

// 组件一
export class OneComponent implements OnInit {
constructor(private sharedService: SharedService) {}
ngOnInit(): void {
this.sharedService.setData(value); // 需要共享的数据
}
}

// 组件四
export class FourComponent implements OnInit {
constructor(private sharedService: SharedService) {}
ngOnInit(): void {
this.sharedService.getData.subscribe(data => /处理共享数据/);
}
}

当然,更好的方法是使用异步管道而不是订阅。但现在你有一个方向。

英文:

You can use service.

// Service
@Injectable({
  providedIn: 'root'
})
export class SharedService {
  private data$ = new BehaviorSubject<DataInterface>(null); 
  get getData(): Observable<DataInterface> {
    return this.data$.asObservable();
  } 
  set setData(value: DataInterface): void {
    this.data$.next(value);
  }
}

// Component One
export class OneComponent implements OnInit {
  constructor(private sharedService: SharedService) {}
  ngOnInit(): void {
    this.sharedService.setData(value); // data you need to share
  }
}

// Component Four
export class FourComponent implements OnInit {
  constructor(private sharedService: SharedService) {}
  ngOnInit(): void {
    this.sharedService.getData.subscribe(data => /*handle shared data*/); 
  }
}

Of course the better way is to use async pipe instead subscription. But now you have direction.

答案2

得分: 2

在Angular中,你可以使用服务来在组件之间传递数据,而无需使用属性传递的方式。你可以使用服务来作为一个集中位置来共享数据和功能给各个组件。

// my-service.ts

import { Injectable } from '@angular/core';

@Injectable({
    providedIn: 'root'
})
export class MyService {
    private myData: any;

    constructor() {}

    updateData(data: any) {
        this.myData = data;
    }

    getData() {
        return this.myData;
    }
}

你需要将这个服务提供给根模块,以便在你的应用程序中使用它。

// app.module.ts
import { NgModule } from '@angular/core';
import { MyService } from './my-service';

@NgModule ({
    providers: [MyService]
})
export class AppModule { }

现在,你可以在组件中使用这个服务,但在此之前,你需要通过组件构造函数将服务注入到组件中。

import { Component } from '@angular/core';
import { MyService } from './my-service';

@Component({
    selector: 'app-parent-component',
    template: '<app-child-component></app-child-component>'
})

export class ParentComponent {
    constructor (private _myService: MyService) {}

    setData() {
        this._myService.updateData("要更新的数据内容!!")
    }
}

现在,你可以在你的子组件、孙子组件甚至兄弟组件中访问这些数据。

export class GrandchildComponent {
    myData: any;

    // 同样,在这里,你需要通过组件构造函数将服务注入到组件中。
    constructor (private _myService: MyService) {}

    getData() {
        this.myData = this._myService.getData()
    }
}
英文:

In Angular, you can use services to pass data between components without resorting to prop drilling. You can use services that act as a centralized location for sharing data and functionality across components.

//my-service.ts

import { Injectable } from &#39;@angular/core&#39;;

@Injectable({
    providedIn: &#39;root&#39;
})
export class MyService {
    private myData: any;

    constructor() {}

    updateData(data: any) {
        this.myData = data;
    }

    getData() {
        return this.myData;
    }
}

You have to provide the service to the root module, In order to use it in your application.

// app.module.ts
import { NgModule } from &#39;@angular/core&#39;;
import { MyService } from &#39;./my-service&#39;;

@NgModule ({
    providers: [MyService]
})
export class AppModule { }

Now You can use the service in the component but before that, you have to inject the service into the component using the component constructor.

import { Component } from &#39;@angular/core&#39;;
import { MyService } from &#39;./my-service&#39;;

@Component({
    selector: &#39;app-parent-component&#39;,
    template: `&lt;app-child-component&gt;&lt;/app-child-component&gt;`
})

export class ParentComponent {
    constructor (private _myService: MyService) {}

    setData() {
        this._myService.updateData(&quot;whatever the data you want to update here!!&quot;)
    }

}

Now You can access the data in your ChildProcess, grandChild, or even in the sibling component.

export class GrandchildCompoent {
    myData: any;

    // Same here, you have to inject the service to the component using the component constructor.
    constructor (private _myService: MyService) {}

    getData() {
        this.myData = this._myService.getData()
    }

}

huangapple
  • 本文由 发表于 2023年6月4日 23:16:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76401075.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定