【问题标题】:Call a Components function from a Service - possible cyclic dependency - Angular从服务调用组件函数 - 可能的循环依赖 - Angular
【发布时间】:2019-03-24 02:17:25
【问题描述】:

我希望能够从我的参与服务(服务)中的 filterComponent(组件)调用一个函数

我的 filterComponent 中的函数访问一个位于engagementService 中的数组 - 它使用该数组的数据添加到它的 html 模板中的单选按钮中。

它成功访问了数组,因为我在 filterComponents 构造函数中包含了engagementService(我通过点击函数对其进行了测试,但在功能上这不起作用,因为我需要单选按钮在加载后具有名称)。

这个数组的数据是在我的主页加载后填充的,因为数据是从engagementService中的端点检索的,所以我希望仅在加载图表后(异步)调用这个函数,图表函数在engagementService,以及其他代码,在数组填充数据后,我可以从我的 filterComponent 中有效地调用此函数,因此它可以工作。

我可能没有以最好的方式做到这一点,因为我在engagementService 中有一个数组,该数组填充了来自端点的数据,然后我想从使用该数组的engagementService 中的filterComponent 调用该函数。

因此,数据正朝着一种方向发展,而不是另一种方向。我有第二个组件,我也可以在其中调用该函数,因为我在那里调用图形函数,但我也遇到了同样的问题。

如果我在构造函数中添加组件类,我会得到“无法解析 EngagementService 的所有参数:([object Object], ?)。”

如果我只是将类作为变量包含在内,它也不起作用。

我的过滤器组件: 我可以在构造函数中成功调用我的服务(engagementService, 我从那里访问数组 - this.engagementService.orgSubSidNames。

  @Injectable()
  export class EngagementFilterComponent implements OnInit {
  public subsidiaryForm: FormGroup;
  public subsidiaryOptions: Array<RadioButtonGroupOptions>;
   public orgSubSidNames = [];

  @Output() updateSubSids = new EventEmitter;

  constructor(private builder: FormBuilder, public engagementService: EngagementService) { }

  ngOnInit(): void {

    this.subsidiaryForm = this.builder.group({ subsidiary: new FormControl() });
    this.subsidiaryForm.valueChanges.subscribe(data => this.updateSub(data.subsidiary, resolve));

  namesAsOrgs({ includeOpportunities, orgSubSidNames }) {
    return orgSubSidNames.map((name, i) => {
      return {
        label: name,
        value: `${i}`,
        selected: this.includeOpportunities
      }
    })
  }

  subSidNamesToRadioButton() {
    console.log('we are calling here within the subsidnamesto radio button ')
    const subSids = this.namesAsOrgs({
      includeOpportunities: true,
      orgSubSidNames: this.engagementService.orgSubSidNames
    })

    this.subsidiaryOptions = subSids;
  }

我的服务: (如果我在构造函数中包含了engagementFilter,或者甚至只是在系统不加载的类中调用了该类,并且在构造函数中它给出了一个错误,提示“无法在engagementService 构造函数中解析对象参数”。

Getordsubsiaries 创建名称数组,然后将其保存在组件函数中调用的 orgSubSidNames 中。这行得通!但当然我需要异步调用该函数,因为名称是由端点检索的。

    @Injectable()
   export class EngagementService {
  public orgSubSidIds = [];
  public graphParams: IGraphParams = {

  }

  constructor(private http: WefHttp) {
    this.baseURL = `${environment.ews_api_host}/${ENDPOINTS.api}`;
    this.organization = this.focus = new EngagementRoot();
  }


  getOrgSubsidiaries(id) {
    return this.organizationSubsidiaries(id)
  .subscribe(data => {
    console.log('subsidiaries data' + JSON.stringify(data));

    let subsidiaryNames = []
    data.forEach(sub => {
      subsidiaryNames.push(sub.SubsidiaryName)
    })
    subsidiaryNames = subsidiaryNames.filter(this.onlyUnique);

    this.orgSubSidNames = subsidiaryNames;

  });
 }

第一次加载系统时调用此 getOrgSubsidiaries。

【问题讨论】:

  • 如果我正确理解您的问题,您正在尝试将EngagementFilterComponent 组件添加到您的EngagementService 服务中。这不起作用,对吗?
  • 是的!如果有歧义,我很抱歉
  • 在这种情况下,您的实现会在 2 个类中导致 循环依赖,因此您会遇到错误。我不清楚您的要求是否要为此发布答案。您介意详细说明或编辑问题以帮助其理解吗?
  • 当然,我认为你是对的。我压力很大,不能准确地表达自己。我将更改文本以更好地描述我的意图。
  • 好的,我进行了编辑

标签: javascript angular


【解决方案1】:

您目前正在做的事情是不可能的。您不能在 service 构造函数或任何其他 component's 构造函数中注入组件。 这不是控制component 的方法。

如果你真的想从服务中调用组件的方法,那么你可以使用Subject或BehaviorSubject,然后从组件中订阅它。

service.ts

private _source = new BehaviorSubject<boolean>();
public source$ = this._source.asObservable();   // observable to be subscribed from the component

getOrgSubsidiaries(id) {
    return this.organizationSubsidiaries(id)
        .subscribe(data => {
            console.log('subsidiaries data' + JSON.stringify(data));

            ...........................
            this.orgSubSidNames = subsidiaryNames;

            //emit event
            this._source.next(true);
        });
}

组件.ts

constructor(private builder: FormBuilder, public engagementService: EngagementService) { }

ngOnInit(){
   // subscribe to emitter(BehaviourSubject) of service
   this.engagementService.source$.subscribe(
   (data)=>{
       if(data){
           // call component method here every time when event is emitted
       }
   })
}

【讨论】:

  • 这更像是我真正需要的,所以基本上只有在收到数据之后,然后调用我的函数——不过实际上是从我的组件文件中调用它,我更喜欢!
  • 是的,这是一个需要遵循的解决方法。从组件本身间接调用component 的方法,但仅当服务通过BehaviorSubject 通知这样做时才这样做
  • 我现在只是想试试,我还没有听说过这个!我听说过 observables,但我认为它们不适用于这种情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-18
  • 2021-02-02
  • 1970-01-01
  • 2014-08-03
相关资源
最近更新 更多