【问题标题】:How do I transfer data between a shared class and an angular 2 component?如何在共享类和 Angular 2 组件之间传输数据?
【发布时间】:2018-09-27 02:26:32
【问题描述】:

我正在使用独立的 TypeScript 类调用我的后端服务。在实例化我的共享类的实例时,我能够console.log 捕获的数据。但是,我无法在我的 Angular 组件中访问该类的本地属性和方法。

这是我的组件:

import { Component, OnInit } from '@angular/core';
import { ProjectService } from '../shared/projectService';
import { HttpClient } from '@angular/common/http';

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

export class AboutComponent implements OnInit {

  projects: any;
  windowWidth: number;
  service: ProjectService;

  constructor(private httpClient: HttpClient) { 
    this.service = new ProjectService(this.httpClient);
    //  returns as undefined
    console.log(this.service.getAllProjects());   
  }

  ngOnInit() {
    this.windowWidth = window.innerWidth;
  }

}

这是我的共享类模块:

import { HttpClient } from '@angular/common/http';

interface Project {
    demoURL: string,
    githubURL: string,
    imgFileName: string,
    name: string,
    stack: Array<string>
}

export class ProjectService {

    private configURL = `https://someURL.herokuapp.com/getAllProjects`;
    projects: any;
    constructor(private httpClient: HttpClient) {

        this.httpClient.get(this.configURL).subscribe(resp => {
            this.projects = resp;
        });
    }

    getAllProjects() {
        return this.projects;
    }
}

如你所见,

我想使用this.service.getAllProjects() 在我的ng 组件中填充我的局部变量projects。当我尝试记录来自共享类ProjectService 的响应时,函数响应为undefined

当我在使用new 初始化类之后在ProjectService 构造函数中console.log 时,我可以看到我的类能够捕获响应。

为什么要这样做?还有,怎么解决?

谢谢大家。

【问题讨论】:

    标签: typescript angular6 angular-httpclient typescript-class


    【解决方案1】:

    正如 user1986938 所指出的,您的问题是您的 API 调用是异步的,您必须等待 API 响应才能对您的数据执行某些操作。
    Angular 中,您可以依靠与Angular 紧密耦合的RxJs 库轻松做到这一点。

    这是一个working example,您可以轻松适应您的情况。

    您可以看到,在此示例中,我使用了 ReplaySubject,因为它能够再次为任何新订阅者提供价值,即使在您的 API 调用完成后也是如此。
    具体来说,这允许您从您的ProjectService 多次查询您所有项目的列表,并且可能从您的应用程序的不同部分查询,而无需多次执行真正的 API 调用,也无需关心其他任何事情。

    如果您不熟悉ReactiveX 的概念,我建议您阅读这篇很棒的documentation,对于您的情况,这个part 大约是Subjects

    组件

    export class AppComponent
    {
        // this property allows passing projects to your template
        projects: string[];
    
        // you can directly inject your service into your component constructor
        constructor ( private projectService: ProjectService )
        {
            // here you subscribe to you projects query observable
            this.projectService.getAll().subscribe(projects =>
            {
                // now you can do what you want with your projects
                console.log('projects: ', projects);
                // here, we store projects in component property to display them in template
                this.projects = projects;
            });
        }
    }
    

    服务

    export class ProjectService
    {
        // this property is used to store your API response
        private projectsSubject: ReplaySubject<any>;
    
        constructor ()
        {
            // create subject
            this.projectsSubject = new ReplaySubject();
    
            // do API call
            this.doFakeAPICall().subscribe(projects =>
            {
                // store response as subject value
                this.projectsSubject.next(projects);
            });
        }
    
        getAll (): Observable<any>
        {
            // return subject as observable
            return this.projectsSubject.asObservable();
        }
    
        // replace this be your real API call
        private doFakeAPICall (): Observable<any>
        {
            // here we simulate a response delay of one second
            return of([ 'project 1', 'project 2' ]).pipe(delay(1000));
        }
    }
    

    【讨论】:

      【解决方案2】:

      实例化 ProjectService 对象时,您无需等待响应完成。尚未设置项目属性。我建议您将 behaviorSubject 用于项目属性。您可以阅读主题和行为主题here

      【讨论】:

        【解决方案3】:

        好的,所以对我有用的是在 http 请求完成时使用 EventEmitter 发出项目,正如 user1986938 所述。

        这就是我所做的:

        HttpService:

        import { HttpClient } from '@angular/common/http';
        import { Injectable, EventEmitter } from '@angular/core';
        import { Project } from '../shared/project.interface';
        
        @Injectable()
        export class ProjectService {
        
            private configURL = `https://someURL.herokuapp.com/getAllProjects`;
            public httpResponse = new EventEmitter<Project[]>();
            public projects: Project[];
        
            constructor(private httpClient: HttpClient) {
                this.httpClient.get(this.configURL).subscribe((res: Project[]) => {
                    this.projects = res;
                    this.httpResponse.emit(this.getProjects());
                });
            }
        
            getProjects() {
                return this.projects.slice();
            }
        }
        

        组件:

        import { Component, OnInit } from '@angular/core';
        import { ProjectService } from '../shared/project.service';
        import { Project } from '../shared/project.interface';
        
        @Component({
          selector: 'app-about',
          templateUrl: './about.component.html',
          styleUrls: ['./about.component.css'],
          providers: [ProjectService]
        })
        
        export class AboutComponent implements OnInit {
        
          projects: Project[];
          windowWidth: number;
        
          constructor(private projectService: ProjectService) { 
          }
        
          ngOnInit() {
            this.windowWidth = window.innerWidth;
        
            this.projectService.httpResponse.subscribe(([first, second]: [Project, Project]) => {
                console.log(first);
                console.log(second);
            });
          }
        
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-11-06
          • 2019-08-03
          • 2017-05-06
          • 1970-01-01
          • 2023-03-10
          • 2020-03-14
          • 2017-10-01
          • 1970-01-01
          相关资源
          最近更新 更多