过滤从Web服务获取的json数组仅包含某些元素 - Angular

时间:2017-09-14 13:41:08

标签: json angular typescript http-get angular-filters

我正在创建一个项目,该项目使用来自Web服务的HTTP get并返回一个项目数组,包括ID,名称,描述等。

此Web服务中有许多项目,但我只关注其中的9项,其余项目无关紧要。

我有一组9个项目,在project.service.http.ts类中声明了我想要显示的唯一ID。

我正在尝试过滤HTTP get请求,只包含9个特定的ID,我将它存储在string类型的projectIds数组中。

EDIT2: 记录响应: enter image description here

编辑解决: 我从:

更改了project.viewer.component中的构造函数
 constructor(private service: ProjectService) {
        this.service.fetchProjects().subscribe(response => {
          this.projects = response.filter(elements => {
            // BaseComponent was my class. Use yours.
            return ProjectViewerComponent.projectIds.includes(elements.id);
          });
        })
      }

到:

 constructor(private service: ProjectService) {
        this.service.fetchProjects().subscribe(response => {
          this.projects = response['project'].filter(elements => {
            // BaseComponent was my class. Use yours.
            return ProjectViewerComponent.projectIds.includes(elements.id);
          });
        })
      }

关键是this.projects = response

之后的['项目']

project.service.http.ts:

@Injectable()
export class ProjectServiceHttp extends ProjectService {

    //variables
    baseUrl = "http://...";

        static projectIds: string[] = ["..."
                                ,"...", "..","..."];

        //constructor
       constructor(private http: Http) {
            super();
        }

    //methods
    fetchProjects(): Observable<any>{
        let headers = new Headers({'Content-Type': 'application/json'});
        let options = new RequestOptions({headers: headers});
        return this.http.get(this.baseUrl, options)
          .map((response: Response) => response.json())
          .catch(this.handleError);
      }

        private handleError(error: any) {
            // In a real world app, we might use a remote logging infrastructure
            // We'd also dig deeper into the error to get a better message
            let errMsg = (error.message) ? error.message :
                error.status ? `${error.status} - ${error.statusText}` : 'Server error';
            console.log(errMsg); // log to console instead
            return Observable.throw(errMsg);
        }
}

project.viewer.component.ts:

@Component({
    selector: 'project-viewer',
    templateUrl: './project-viewer.html',  
    styleUrls: ['./project-viewer.css']
})


export class ProjectViewerComponent  {
    name = 'ProjectViewerComponent';
    projects: Project[] = [];

    static testIds: string[] = ['qqq', 'aaa'];

    static projectIds: string[] = ["...","..."
    ,"..","..","...","..."
    ,"..", "...","..."];

    errorMessage = "";
    stateValid = true;

      constructor(private service: ProjectService) {
        this.service.fetchProjects().subscribe(response => {
          this.projects = response.filter(elements => {
            return ProjectViewerComponent.projectIds.includes(elements.id);
          });
        })
      }

    private raiseError(text: string): void {
        this.stateValid = false;
        this.errorMessage = text;
    }
}

项目viewer.html:

<h3>Projects </h3>
<div >
    <ul class= "grid grid-pad">
        <a *ngFor="let project of projects" class="col-1-4">
            <li class ="module project" >
                <h4 tabindex ="0">{{project.name}}</h4>
            </li>
        </a>
    </ul>
</div>

2 个答案:

答案 0 :(得分:2)

您服务中的方法fetchProjects()可以在其他组件中重复使用。因此,您可能希望它返回所有项目,因为这是此方法的目标。获取所有项目。

第一种方法(推荐):

最好的办法是过滤返回HTTP呼叫所获得的数据。

这样,您需要过滤从服务中获得的数据,以便仅显示该组件中的内容。

project.viewer.component.ts:

.subscribe(response =>{
  this.projects = response.project.
    .filter(elements => someCondition);
  console.log(response);
  console.log(this.projects);
},

第二种方法(不推荐):

您唯一希望使用.map()方法更改服务电话中获得的数据的时间是您确定无法获得所有项目,但只有这些那些。当然,您可以执行另一个调用相同URL但不过滤该数据的函数,但是您必须维护两个基本上执行相同调用的方法。这就是为什么在您的组件中而不是在您的服务中过滤数据更好的原因。

但是,您需要在服务中更改此部分:

project.service.http.ts:(应该叫做 project.service.ts btw)

.map((response: Response) => {
  const results = response.json();
  return = results.filter(elements => someCondition);
})

编辑:以下是您的类对象和我自己的模拟数据的工作解决方案:

project.service.http.ts 初始的,不要使用.filter()

fetchProjects(): Observable<any>{
  const headers = new Headers({'Content-Type': 'application/json'});
  const options = new RequestOptions({headers: headers});
  return this.http.get(this.baseUrl, options)
    .map((response: Response) => response.json())
    .catch(this.handleError);
}

project.viewer.component.ts:

您需要调整一下,因为我花了一些代码来做一个快速的例子(我的项目ID是'qqq''aaa')。

  static projectIds: string[] = ['yourIds', 'YourIds2', ...];

  projects: Project[] = [];

  constructor(private service: ProjectService) {
    this.service.fetchProjects().subscribe(response => {
      this.projects = response.filter(element => BaseComponent.projectIds.includes(element.id)); // BaseComponent was my class. Use yours.
    })
  }

project-viewer.html: 不变。

在我的示例中,我的服务向我发送了4个项目,并且我将其中的2个过滤为仅显示2.工作得很好,告诉我您是否有任何问题适应您的代码。

如您所见,这是我首先提到的第一种方法的应用。由于第二种方法中所述的原因,请不要将此应用于服务。

答案 1 :(得分:0)

您可以使用pipe根据您的条件过滤这些项目(仅针对那些“唯一ID”),并将其应用于模板中的*ngFor,如下所示,

<a *ngFor="let project of projects | uniqueOnes" class="col-1-4">

像这样定义管道,

@Pipe({
  name: 'uniqueOnes'
})
export class UniqueOnesPipe implements PipeTransform {
  uniqueIds = [ 'id1', 'id2', 'id5'];

  transform(value: any): any {
    return value
            ? value.filter(project => { return <condition to pass only the unique projects (For ex: this.uniqueIds.indexOf(project.id) !== -1)>  })
            : value;
  }

}

有关管道的更多信息here