简体   繁体   English

角度组件:不可能使用 TypeScypt 循环遍历对象数组

[英]Angular Component: Impossible to loop through an array of object with TypeScypt

can any one please tell me why I can not loop through this array?谁能告诉我为什么我不能遍历这个数组? In ngOnInit, everything works fine.在 ngOnInit 中,一切正常。 I got an array that I successfully display in the template.我得到了一个在模板中成功显示的数组。 But in ngAfterViewInit, console.log show the array but when looping through with "for of" or "forEach", nothing works.但是在 ngAfterViewInit 中,console.log 显示数组,但是当使用“for of”或“forEach”循环时,没有任何效果。

import { JobsService } from '../jobs.service';
import {Job} from '../models/Job';

@Component({
    selector: 'app-job',
    templateUrl: 'job.component.html'
})

export class JobComponent implements OnInit, AfterViewInit {
    title = 'Job';
    jobs: Job[] = [];
    InProcess = '';
    CurrentPartner = '';
    ShowProcess = false;
    sended = '';

    constructor(private jobsService: JobsService) {
    }

    ngOnInit() {
        this.jobs = this.jobsService.getJobs();
    }
    ngAfterViewInit() {
      console.log(this.jobs); // Show the array

      // Nothing happened when looping through the array
      this.jobs.forEach((oneJob) => {
        console.log(oneJob);
      });
    }
}

Screenshot of the console in Google Chrome Google Chrome 中的控制台屏幕截图

The content of the service:服务内容:

import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import {Job} from './models/Job';

interface IJob {
  message: string;
  jobs: any[];
}

@Injectable({
  providedIn: 'root'
})

export class JobsService {
  constructor(private httpClient: HttpClient) { }
  private REST_API_SERVER = 'http://localhost:8080/myband/api/getjobs.php';
  private REST_API_SERVER_SEND = 'http://localhost:8080/myband/api/sendjob.php';
  jobList: Job[] = [];
  errorMessage: any;
  message: string;

  static handleError(err: HttpErrorResponse) {
    let errorMessage = '';
    if (err.error instanceof ErrorEvent) {
      errorMessage = `An error occurred: ${err.error.message}`;
    } else {
      errorMessage = `Server returned code: ${err.status}, error message is: ${err.message}`;
    }
    console.error(errorMessage);
    return throwError(errorMessage);
  }

  public getJobs() {
    this.requestJobs().subscribe(
      iJob => {
        this.message = iJob.message;
        for (const job of iJob.jobs) {
          const oneJob: Job = new Job(job);
          this.jobList.push(oneJob);
        }
      },
      error => this.errorMessage = error as any
    );
    return this.jobList;
  }

  public requestJobs(): Observable<IJob> {
    return this.httpClient.get<IJob>(this.REST_API_SERVER).pipe(
       catchError(JobsService.handleError)
    );
  }
}

The first thing I want to say to you is about isolation of responsibilities.我想对你说的第一件事是关于责任的隔离。

Your service must have just one job: provider one way to access your data;您的服务必须只有一项工作:提供一种访问您数据的方式; It means your logic inside getJobs() method could be done in your component.这意味着您在getJobs()方法中的逻辑可以在您的组件中完成。

export class JobsService {
    constructor(
        private httpClient: HttpClient,
    ) {}
    private REST_API_SERVER = 'http://localhost:8080/myband/api/getjobs.php';

    public requestJobs(): Observable<IJob> {
        return this.httpClient.get<IJob>(this.REST_API_SERVER);
    }
}

Now, you can handler your data in your component.现在,您可以在组件中处理数据。

import { JobsService } from '../jobs.service';

@Component({
    selector: 'app-job',
    templateUrl: 'job.component.html'
})

export class JobComponent implements OnInit, AfterViewInit {
    title = 'Job';
    jobs$;
    InProcess = '';
    CurrentPartner = '';
    ShowProcess = false;
    sended = '';

    constructor(private jobsService: JobsService) {
    }

    ngOnInit() {
        this.jobs$ = this.jobsService.requestJobs();
    }



    ngAfterViewInit() {
        this.jobs$
            .pipe(
                map(() => {}), // change your data here
                catchError(() => {}) // handler your error here;
            )
            .subscribe(
                () => {} // have access to your final data here. 
            );
    }
}

Things to know:须知:

  1. You can remove the subscribe() execution and use the async pipe in your template;您可以删除subscribe()执行并在模板中使用异步管道

  2. The use of the operator map in pipe() is optional, you can handler your final data directly from your first callback subscribe() .pipe()使用运算符映射是可选的,您可以直接从第一个回调subscribe()处理最终数据。

  3. You can convert your Observable to Promise using toPromise() method in one observable.您可以在一个 observable 中使用toPromise()方法Observable转换为Promise Don't forgot async / await in your ngAfterViewInit .不要忘记ngAfterViewInit async / await

Let me know if there is something I can help.如果有什么我可以帮忙的,请告诉我。

Try:尝试:

Object.keys(this.jobs).forEach(job => {
    console.log(this.jobs[job]);
});

Try to assign an iterator function with below part replacement by this code:尝试通过以下代码分配具有以下部分替换的迭代器函数:

// Nothing happened when looping through the array
this.jobs.forEach(oneJob, function(value, key) {
    console.log(key + ': ' + value);
});

Usage of forEach in AngularJS: AngularJS 中 forEach 的用法:

For documentation try to check AngularJS forEach Docs对于文档,请尝试检查AngularJS forEach Docs

Syntax:句法:

someIterable.forEach(object, iterator, [context]) someIterable.forEach(对象,迭代器,[上下文])

Please check below example请检查以下示例

class Job {
    id: any;
    status: any;
    constructor(obj: any) {
        this.id = obj.id;
        this.status = obj.status;
    }
}

let arr = [
    {
        id: 1,
        status: "job"
    }, {
        id: 2,
        status: "job2"
    }
];

let newArr: any = [];

arr.forEach(a => {
    let obj: Job = new Job(a);
    newArr.push(obj);
})

console.log(newArr);

newArr.forEach((a: any) => {
    console.log(a);
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM