我错过了NGFO和异步管



在我看来它应该可以工作,但是我得到了一个模板错误: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.

模板:

<div class="block-header">
    <h2>{{ policyName }}</h2>
</div>
<div *ngFor="let p of policies | async" class="card event-card">
    <div class="card-header">
        <h2>{{ p.title }}</h2>
    </div>
    <div class="card-body card-padding">
        <div [markdown]="p.description"></div>
    </div>
</div>

组件:

export class PoliciesComponent implements OnInit {
  name: string = 'policies';
  //public policies: Policy[];
  public policies: Observable<Policy>;
  constructor(
    private policyService: PolicyService,
    private route: ActivatedRoute) { }
  ngOnInit(): void {
    // this.route.params is an observable of the child (category) routes under /policies
    this.route.params.subscribe((p: Params) => this.loadPolicies(p['category']))
  }
  loadPolicies(category: string): void {
    let policyCategory = PolicyCategory.ClubPolicy;
    if (category === 'rules') {
      policyCategory = PolicyCategory.LocalRule;
    } else if (category === 'handicaps') {
      policyCategory = PolicyCategory.Handicaps;
    }
    this.policies = this.policyService.loadPolicies(policyCategory);
    // this.policies = [];
    // this.policyService.loadPolicies(policyCategory).subscribe(p => this.policies.push(p))
  }
}

服务:

loadPolicies(category: PolicyCategory): Observable<Policy> {
    return this.dataService.getApiRequest('policies')
        .mergeAll() // turn Observable<any> where any=collection into Observable
        .map((p: any) => new Policy().fromJson(p))
        .filter((policy: Policy) => policy.category === category)
}

使用替换代码(在组件中的注释中),一切都起作用,但是我将不得不退订订阅。我觉得我正在做正确的事情,但是我的浏览器不同意。

我误解了异步如何与可观察的可观察到的?

问题的答案"我在误解什么?"是,太多了。

我认为,

最重要的是,在尝试进行更具反应性的编程方式时,请理解服务的作用。它应该做的不仅仅是通过。

基于Cory Rylan的阅读帖子,我得出的结论是,我的服务应以不同的方式管理数据。末尾的概述部分尤其值得阅读。

因此,虽然我没有在原始帖子中重新设计服务,但我确实有一个很好的模式用于粗糙服务。该服务具有我的组件订阅的数据存储。该动作突变该数据存储,并在可观察物的奇迹中,当商店随着这些操作而更改时,它们会自动更新。

用您要管理的任何对象替换" profilerjob":

@Injectable()
export class ProfilerJobService {
    private resource: string = 'profile';
    private _jobs: BehaviorSubject<ProfilerJob[]>;
    private store: {
        items: ProfilerJob[]
    };
    constructor(private dataService: DataService) {
        this.store = {
            items: []
        };
        this._jobs = <BehaviorSubject<ProfilerJob[]>>new BehaviorSubject([]);
    }
    get jobs(): Observable<ProfilerJob[]> {
        return this._jobs.asObservable();
    }
    selectJob(id: string): Observable<ProfilerJob> {
        if (id === 'new') {
            return Observable.of(new ProfilerJob());
        }
        return this._jobs.map(jobs => {
            let job = jobs.find(item => item.id === id);
            return _.clone(job);
        });
    }
    loadJobs(filter: JobFilter = null): void {
        let url = this.resource;
        let params: any;
        if (filter) {
            url = url + '/search';
            params = filter.toSearchApi();
        }
        this.dataService.getData(url, params).subscribe(data => {
            this.store.items.length = 0;
            data.forEach((d: any) => this.store.items.push(new ProfilerJob().fromJson(d)));
            this._jobs.next(_.cloneDeep(this.store).items);
        });
    }
    loadJob(id: string): void {
        this.dataService.getData(`${this.resource}/${id}`).subscribe(json => {
            let found = false;
            this.store.items.forEach((item, index) => {
                if (item.id === json.id) {
                    this.store.items[index] = new ProfilerJob().fromJson(json);
                    found = true;
                }
            });
            if (!found) {
                this.store.items.push(new ProfilerJob().fromJson(json));
            }
            this._jobs.next(_.cloneDeep(this.store).items);
        });
    }
    addJob(job: ProfilerJob): Observable<void> {
        return this.dataService.postData(this.resource, job.toJson())
            .do((json: any) => {
                this.loadJob(json.id);
            });
    }
    updateJob(job: ProfilerJob): Observable<void> {
        return this.dataService.putData(`${this.resource}/${job.id}`, job.toJson())
            .do(() => {
                this.loadJob(job.id);
            });
    }
    deleteJob(job: ProfilerJob): Observable<void> {
        return this.dataService.deleteData(`${this.resource}/${job.id}`)
            .do(() => {
                let idx = this.store.items.findIndex(j => j.id === job.id);
                this.store.items.splice(idx, 1);
                this._jobs.next(_.cloneDeep(this.store).items);
            });
    }
}

最新更新