簡體   English   中英

從服務訪問組件數據

[英]Access component data from a service

我在Angular 7中有一個調用API的服務,我想使用API​​調用中組件收集的一些數據。 這是組件的相關部分:

import { Component, OnInit } from "@angular/core";
import { IPrompt } from './prompt';
import { PromptService } from './prompt.service';
import { DropdownService } from '../dropdown.service'
import { FormGroup, FormControl, ReactiveFormsModule } from '@angular/forms';
import { IQuery } from './prompt'
import { NgxSpinnerService } from 'ngx-spinner';

import { Query } from '../dropdown.service';


@Component({
  selector: 'pm-prompts',
  templateUrl: './prompt-list.component.html',
  styleUrls: ['./prompt-list.component.css']
})

export class PromptListComponent implements OnInit 
{

  public get searchArray(): string[] 
  {
  return [ this.searchForm.controls['searchQuery'].value, this.searchForm.controls['region'].value, 
  this.searchForm.controls['status'].value, this.searchForm.controls['language'].value, 
  this.searchForm.controls['inputMode'].value ];
  }

  public get QueryString(): string
  { 
    var query = new Query(this.searchForm.controls['searchQuery'].value, this.searchForm.controls['region'].value, 
    this.searchForm.controls['status'].value, this.searchForm.controls['language'].value, 
    this.searchForm.controls['inputMode'].value, this.searchArray);
    return query.getQuery;
  }
}

我從上面的示例中刪除了所有不必要的字段。 基本上,我想從名為PromptService的服務訪問此組件中的get QueryString()方法。 如果需要,我也可以包括該服務的代碼。 我已經對此進行了研究,但是我看到的所有問題都詢問了如何在組件中使用服務中的數據,而不是相反。

我嘗試將組件導入服務,然后使用:

queryString = PromptListComponent.QueryString()

但是我收到一條錯誤消息,提示“類型'typeof PromptListComponent'上不存在屬性'QueryString'”。 我覺得有一個簡單的解決方法,但是我沒有運氣找到它或弄清楚它。

您可以將組件導入服務並在構造函數中對其進行定義,它會生成該組件的實例,然后可以從該組件的實例訪問方法和屬性:

在您的服務文件中:

import { PromptListComponent } from './path-to-your-component';
import { Injectable } from '@angular/core';

@Injectable({providedIn:'root'}) //Or import to providers
export class PromptService {
 //Define it in your service constructor
 constructor( private promptListComponent: PromptListComponent){}

 //You now have generated an instance of that component
 getQueryFromPromtListComponent() {
   console.log(this.promptListComponent.QueryString())
 }
}

您看到的所有內容都是關於從組件中的服務訪問數據的原因,是因為您已反轉控件。 您的邏輯應該是組件正在將這些數據推送到服務,而不是服務正在從您的組件中提取此數據。

您的理論服務應該具有某種setQueryString(queryString: string)方法,該方法接受查詢字符串作為參數,並且只要查詢字符串發生更改,您的組件就會調用該服務方法。 由於您已經在使用反應形式,所以這很簡單!

this.searchForm.valueChanges.subscribe(value => this.myService.setQueryString(this.QueryString));

有許多替代方法可以執行此操作,但是原理應該相同,數據始終在推送,從不提取。

假定您不是在偵聽來自UI的事件,而是在服務中執行需要獲取組件屬性的操作。

我利用訪客模式來實現此解決方案。

根據提供的示例代碼,您似乎缺少了幾件事。

  1. 屬性不能通過類類型訪問,只能使用靜態成員來完成。
  2. 要訪問屬性(非靜態),您需要獲取組件實例。 它需要傳遞給服務。

好的,既然我們有一些需要處理的背景,讓我們看一下實現您所尋找的目標的潛在方法

  1. 通過構造函數將服務(PromptService)作為依賴項添加到組件。 這將幫助您的服務直接引用您的UI組件。
  2. 創建您的組件將實現的接口,該接口將定義一個接收屬性名稱的函數,該屬性名稱必須返回值。
public interface IPropertyReader {
   readProperty<T>(prop: string): T
}
  1. 該函數將用於將指定的屬性值返回給調用服務。
@Component({
  selector: 'pm-prompts',
  templateUrl: './prompt-list.component.html',
  styleUrls: ['./prompt-list.component.css']
})

export class PromptListComponent implements OnInit, IPropertyReader
{
   constructor(private promptService: PromptService) {
      promptService.registerComponent(this)
   }
   public readProperty<T>(prop: string):T {
      if (!this.hasOwnProperty(prop)) {
         throw Error(`Property "${prop}" does not exists`);
      }
      return this[prop];
   }   
}
  1. 通過添加一個接收組件實例的函數來修改服務,但是參數類型必須是上述第2點的接口。
@Injectable({ providedIn: 'root' }) 
export class PromptService {
  component: IPropertyReader
  public registerComponent(comp: IPropertyReader) {
     this.component = comp;
     console.log(this.component.readProperty<string>("QueryString"));
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM