【问题标题】:Angular 5 - communication between Components and ServicesAngular 5 - 组件和服务之间的通信
【发布时间】:2018-10-13 11:41:27
【问题描述】:

我使用 Angular 5。 目的是在登录正常时加载数据并在其他组件中使用这些数据。 使用带有 getActiveTasks 方法和 getStats 方法的服务类加载数据。 登录组件:

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent {

  constructor(private auth: AuthenticationService,
              private klinckServices: KlinckServices,
              private router: Router) { }

  loadData($event) {
    console.log('Authentification OK');
    let success;
    this.klinckServices.getActiveTasks(this.auth.getEcmUsername())
      .then((webScriptdata) => {
          console.log('KlinckSercices - loadData');
          success = webScriptdata;
          this.klinckServices.listTasks = success.data as ActiveTask[];
          this.router.navigate([this.klinckServices.getStats()]);
          console.log(this.klinckServices.listServices);
        },
        msg => {
          alert(msg);
          return '';
        });
   // this.router.navigate([this.klinckServices.loadData()]);
  }
}

服务类:

@Injectable()
export class KlinckServices {

  listTasks: ActiveTask[];
  listServices: Stats [] = [];

  constructor(private apiService: AlfrescoApiService,
              private auth: AuthenticationService) {
    console.log('KlinckServices - constructor');
  }
  getStats(): string {
    this.listTasks.forEach((item, index) => {
      if (this.getServicesInListTasks(item.properties.wfvd_nomService) !== null) {
        if (! this.getServicesInListServices(item.properties.wfvd_nomService)) {
          const listLength = this.listTasks.filter(item2 => item2.properties.wfvd_nomService === item.properties.wfvd_nomService).length;
          console.log(listLength);
          const at: ActiveTask[] = [];
          for (let i = 0; i < listLength; i++) {
            at.push(this.listTasks.filter(item2 => item2.properties.wfvd_nomService === item.properties.wfvd_nomService)[i]);
          }
          this.listServices.push({
            data: at,
            count: listLength,
            service: item.properties.wfvd_nomService
          });
        }
      }
    });
    return '/dashboard';
  }
  getServicesInListServices( serviceSearch: string) {
    return(this.listServices.find( x => x.service === serviceSearch));
  }
  getServicesInListTasks( serviceSearch: string) {
    return(this.listTasks.find( x => x.properties.wfvd_nomService === serviceSearch));
  }

加载仪表板组件后,我需要检索这些数据:

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit, AfterViewInit 
{
  @ViewChild(DataTableDirective) datatableElement: DataTableDirective;
  @Input() public klinckServices: KlinckServices;

  listTasks: ActiveTask[];
  listPatients: Patient[];
  listMedecins: Medecin[];
  listDocType: Typologie[];
  listServices: Stats [] = [];
  dtOptions: any = {};
  docNodeId: string;
  detailTaskId: any;

  constructor(private auth: AuthenticationService,
              public dialog: MatDialog,
              private http: HttpClient) 
  {
    console.log('DashboardComponent - constructor');
    this.listServices = this.klinckServices.listServices;
    console.log(this.listServices);
    this.getPatients();
    this.getMedecins();
    this.getDocumentType();
  }

但我在控制台中收到此错误消息:“ERROR TypeError: Cannot read property 'listServices' of undefined”

那么在组件和服务之间进行通信的最佳方式是什么?

【问题讨论】:

    标签: angular service components communication


    【解决方案1】:

    例如,您可以:

    1. 在 Angular 中使用 单例服务并在登录期间加载一次数据
    2. 不是在登录时而是在仪表板初始化时加载数据(接口 U 在类定义中使用的 OnInit 方法 - 并且您必须在构造函数中注入 KlinkService 以将其用作 @CornelC 在他的回答中提到) .

    您的另一个问题:为什么您不在KlinkService.getActiveTasks 上的服务中使用 Rxjs(它是标准的语言)(因为您将其称为承诺)?

    【讨论】:

    • 因为我使用 '@Input' 或 Observable 或 '@Child' 等以不同的方式阅读...我是 Angular 的新手,所以对我来说有点困惑
    • 我更新了我的问题。更多。通常我们不使用@Input 注入服务 - 但是,如果您定义服务接口并为其他项目创建单独的组件库(例如,在单独的 git repo 中)并且组件库需要实现此类接口的服务,这是一个好方法...... - 在这种情况下使用@Input 是可以接受的
    • 好的,如果我理解 '@Input' 是定义接口但不传递数据的好方法,准确吗?
    • 不,通常@Input 用于将变量(参数,对象)传递给我们想要在组件中读取的组件。然而,我们可以放置服务并执行它的方法——但这不是典型的用法。
    【解决方案2】:

    您应该像在LoginComponent 中那样注入服务

    constructor(private klinckServices: KlinckServices
    

    你也应该把它提供给模块

    providers: [KlinckServices]
    

    【讨论】:

      猜你喜欢
      • 2018-08-07
      • 2020-02-05
      • 2019-12-31
      • 2019-03-24
      • 1970-01-01
      • 2019-11-17
      • 2021-03-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多