JavaScript数组不一致

时间:2017-05-04 05:14:19

标签: javascript angular

我有一个数组。我正在努力解决问题,所以......

在我的代码中,我放置了以下调试代码:

console.log(this.pages);
console.log(this.pages.length);

Chrome调试窗口中的输出如下所示。你会看到第一个显示长度:38 ,但第二个console.log显示0.为什么第二个不显示38呢?

enter image description here

import { Injectable } from '@angular/core';
import { AngularFire, FirebaseListObservable } from 'angularfire2';

@Injectable()
export class SitemapService {
    pagesObservable: FirebaseListObservable<any[]>;
    pages: any[] = [];
    data: string = '';
    constructor(
        protected af: AngularFire, 
        private datePipe: DatePipe,
        private urlPipe: UrlPipe
    ){
        this.pagesObservable = this.af.database.list('/pages', { 
            query: {
                orderByChild: 'sortOrder',
                limitToLast: 100
            },
            preserveSnapshot: true
        })
        this.pagesObservable.subscribe(snapshots => {
            snapshots.forEach(snapshot => {
                this.pages.push(JSON.stringify(snapshot.val()));
            })

        })

    }

    getSitemapData(): string {
        let urlBase = location.protocol + '//' + location.host;
        console.log(this.pages);
        console.log(this.pages.length);
        return (this.data);
    }
}

2 个答案:

答案 0 :(得分:0)

试试这个可能是你的工作

alert(Object.keys(this.pages).length);

答案 1 :(得分:0)

不要在构造函数中执行像subscribe这样的异步内容。你无法知道它什么时候完成。 new不是异步的。它不会等待构造函数中的某些异步逻辑在继续之前完成。无论你从哪里调用getSiteMapData,几乎可以肯定,在构造函数中的异步内容有机会完成之前。在您的情况下,只需在构造函数中设置observable。

你对AngularFire列表中的observable如何工作非常困惑。订阅时,您可以获得数据本身。它不会为您提供forEach结束并拍摄val()并执行某些操作的快照。在你的情况下,你不需要,也不想要preserveSnapshots选项,除非你做了一些特别的事情。

import { Injectable } from '@angular/core';
import { AngularFire, FirebaseListObservable } from 'angularfire2';

@Injectable()
export class SitemapService {
    pagesObservable: FirebaseListObservable<any[]>;
    pages: any[] = [];
    data: string = '';
    constructor(
        protected af: AngularFire, 
        private datePipe: DatePipe,
        private urlPipe: UrlPipe
    ){
        this.pagesObservable = this.af.database.list('/pages', { 
            query: {
                orderByChild: 'sortOrder',
                limitToLast: 100
            }
        });
    }

    getSitemapData(): string {
      let urlBase = location.protocol + '//' + location.host;
      this.pagesObservable.subscribe(pages => {
        console.log(pages);
        console.log(pages.length);
      });
  }
}

但是,你说,我希望pages作为我的组件的属性。在你决定要真正做到这一点之前,请确保你不能做到这一点:

<div *ngFor="pagesObservable | async">

这通常是一个更好的解决方案 - 让Angular为您订阅(和取消订阅)。如果您确实需要组件上的pages属性,那么您可以

ngOnInit() {
  this.pagesSubscription = this.pagesObservable.subscribe(pages => this.pages = pages);
}

// MAKE SURE TO DO THIS!
ngOnDestroy() {
  this.pagesSubscription.unsubcribe();
}

但是在将来某个时候你不会有this.pages。因此,如果您想在模板或其他地方使用它,您必须确保它已被设置:

<div *ngIf="pages">I now have the pages!!</div>