【问题标题】:Facing problem in getting service data into component将服务数据导入组件时面临问题
【发布时间】:2018-10-07 08:36:51
【问题描述】:

我正在做一个项目 ->

**

1.

** 我创建了一个服务文件 news.service.ts ,(代码如下) **

2.

** 在服务中,我创建了函数 throwData(),它返回服务的数据

import { Injectable } from '@angular/core';
import { Component, OnInit  } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
  providedIn: 'root'
})
export class NewsService implements OnInit {

  Data: any = [];

  constructor(private http: HttpClient) {
  }

  ngOnInit(): void {

    console.log('f: ' );
    this.http.get('https://newsapi.org/v2/top-headlines?sources=google-news-in&apiKey=5a43238c7827436b9aac37e85583b74a').subscribe(data => {
      this.Data = data['articles'];
      console.log('from service = ' + this.Data[0] );
    });

  }

  throwData(): any {
    return this.Data;
  }
}

**

3.

** 我创建了一个组件文件,即将从服务中获取数据 我尝试使用下面的代码

component.ts 文件

import { Component, OnInit } from '@angular/core';
import {NewsService} from '../service/news.service';

@Component({
  selector: 'app-footer',
  templateUrl: './footer.component.html',
  styleUrls: ['./footer.component.css']
})
export class FooterComponent implements OnInit {

  newData: any = [];

  constructor(private _NewsService: NewsService ) { }

  ngOnInit() {

   this.newData = this._NewsService.throwData();

  }

}

**

4.

** 创建了一个 html 文件以在浏览器中显示数据 component.html 文件

<div class="container">
  <div class="row">
    <div class="col-md-9 each-blog" *ngFor="let item of newData; let i = index"    style="margin-top: 17px ; background-color: #e3e0ef ;  border-left: 5px solid #3d7e9a; ; cursor: pointer;">
     <div>
      <div class="col-md-3">
<img class="img" src="{{item.urlToImage}}" />
      </div>
      <div class="col-md-9">
<a href="{{item.url}}" target="_blank"  style="margin-top:0px">{{item.title}}</a>
<p>{{item.content}}</p> 
      </div>
      </div>
      </div>

    <div class="col-md-3"></div>
  </div>
</div>

但问题是我无法在浏览器中显示数据

【问题讨论】:

    标签: angular angular5 angular6 angular-services


    【解决方案1】:

    您的代码中有许多角度概念错误。

    • 您使用 ngOnInit 在服务中执行请求的方式 服务内容
    • 使用throwData 函数公开数据的方式

    I recommend you reading the angular documentation about services.

    话虽如此,让我试着帮助你:

    您的服务应该类似于:

    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import { Observable, of } from 'rxjs';
    import { switchMap } from 'rxjs/operators';
    
    @Injectable({
      providedIn: 'root'
    })
    export class NewsService {
      data: any[];
    
      constructor(private _http: HttpClient) {}
    
      getData(): Observable<any[]> {
        return !this.data
          ? this._http
              .get(
                'https://newsapi.org/v2/top-headlines?sources=google-news-in&apiKey=5a43238c7827436b9aac37e85583b74a'
              )
              .pipe(
                switchMap(data => {
                  this.data = data['articles'];
                  return this.data;
                })
              )
          : of(this.data);
      }
    }
    

    不要在初始化时获取数据,而是创建一个函数,如果数据未定义则请求数据,如果数据已经存在则返回。

    在组件中:

    import { Component, OnInit } from '@angular/core';
    import { NewsService } from '../service/news.service';
    
    @Component({
      selector: 'app-footer',
      templateUrl: './footer.component.html',
      styleUrls: ['./footer.component.css']
    })
    export class FooterComponent implements OnInit {
    
      newData: any[];
    
      constructor(private _NewsService: NewsService ) { }
    
      ngOnInit() {
       this._NewsService.getData().subscribe(data => this.newData = data);
      }
    }
    

    现在您只是订阅了服务在组件中返回的 observable。

    最后的变化是在你的 HTML 中,在遍历数组之前添加一个 ngIf

    <div class="container">
      <div class="row">
        <div class="col-md-9 each-blog" *ngIf="newData" *ngFor="let item of newData; let i = index"    style="margin-top: 17px ; background-color: #e3e0ef ;  border-left: 5px solid #3d7e9a; ; cursor: pointer;">
         <div>
          <div class="col-md-3">
    <img class="img" src="{{item.urlToImage}}" />
          </div>
          <div class="col-md-9">
    <a href="{{item.url}}" target="_blank"  style="margin-top:0px">{{item.title}}</a>
    <p>{{item.content}}</p> 
          </div>
          </div>
          </div>
    
        <div class="col-md-3"></div>
      </div>
    </div>
    

    我没有对其进行测试,但这应该可以工作,或者至少可以指导您找到解决方案。干杯。

    【讨论】:

    • 你好 @Santiago 当我写 console.log(this.newData);我在控制台中得到结果“未定义”请对此提供帮助
    • @AnuragRanjan ,你在哪里做控制台日志?
    • 在将服务数据放入变量 newData 后,我将其写入 component.ts 文件中
    • 而在service中,在switch map中,API响应data['articles']有值吗?
    【解决方案2】:

    在服务中使用以下代码只是使用http注入来执行请求 它会返回一个 observable 然后在你的组件中订阅这个 Observable 就可以了。

    @Injectable({
      providedIn: 'root'
    })
    export class NewsService {
    
      constructor(private http: HttpClient) {
      }
      fetchDataFromServer(){
          this.http.get('https://newsapi.org/v2/top-headlines?sources=google-news- 
         in&apiKey=5a43238c7827436b9aac37e85583b74a')\
      }
    }
    

    Component.ts

    @Component({
      selector: 'app-footer',
      templateUrl: './footer.component.html',
      styleUrls: ['./footer.component.css']
    })
    export class FooterComponent implements OnInit {
    
      newData$: Observable<any[]>;
    
      constructor(private _NewsService: NewsService ) { }
    
      ngOnInit() {
    
       this.newData$ = this._NewsService.fetchDataFromServer();
    
      }
    
    }
    

    然后在 HTML 模板中使用这个 observable 来显示信息

    <div class="col-md-9 each-blog" *ngFor="let item of newData$ | async">
    </div> 
    

    【讨论】:

    • 也许你需要将服务映射到fetchDataFromServer来获取文章lile.pipe(map (res =&gt; {return res['articles']}))
    猜你喜欢
    • 2017-03-25
    • 1970-01-01
    • 1970-01-01
    • 2021-04-25
    • 1970-01-01
    • 2019-04-15
    • 1970-01-01
    • 1970-01-01
    • 2018-02-17
    相关资源
    最近更新 更多