异步管道不显示来自 observable 的数据

Async Pipe not showing data from observable

昨天,我问了一个关于 . Shortly after, 的问题,为我指出了一个很好的总体方向。我设法 "correctly" 将代码合并到我自己的项目中——也就是说,TypeScript 没有给我任何错误。请参考以下代码片段:

survery.json

[
    {
        "question": "What is your age range?",
        "options": ["10-20","20-30","30-40","40-50"]
    },
    {
        "question": "How did you find us?",
        "options": ["Friend recommendation","Google","Other"]
    },
    {
        "question": "Are you interested in etcetc?",
        "options": ["No","Yes","Meh"]
    }
]

test.model.ts

export interface Test {
    question: string;
    options: string[];
}

test.service.ts

export class TestService {        
    constructor(private http:HttpClient) { 

    }

    getSurveyQuestion(): Observable<Test[]> {
        return this.http
            .get<Test[]>("/path/to/questions.json")
            .do(data => console.log("All : " + JSON.stringify(data)))

    }
}

test.component.ts

export class TestComponent implements OnInit {
    propertyData : Test[] = [];
    sortedData$: Observable<Test[]>;
    sortFn$ = new BehaviorSubject<any>(this.alphabeticalSort);

    constructor(private router: Router, private testService: TestService) {}

    ngOnInit() {
        this.sortedData$ = this.testService.getSurveyQuestion()
            .combineLatest(this.sortFn$)
            .map(([data, sortFn]: [Test[], any]) => {
                return data.sort(sortFn);
            });
    }

    alphabeticalSort() {
        const sortAlphabetAsc = (a: Test, b: Test) => {
            const aQ = a.question.toUpperCase();
            const bQ = b.question.toUpperCase();
            return aQ.localeCompare(bQ);
        };
        this.sortFn$.next(sortAlphabetAsc);
    }
}

test.component.html

<Label [text]="'Sort by alphabetical order'"(tap)="alphabeticalSort()"></Label>
StackLayout *ngFor="let item of sortedData$ | async">
    <Label text="{{item.question}}"></Label>
</StackLayout>

现在,问题是我的应用程序没有显示任何数据。只有按钮(标签)在那里。我的问题是,我哪里出错了? test.service.ts 中的 console.log 确实正确输出了数据:

JS: All : [{"question":"What is your age range?,"options":["10-20","20-30","30-40","40-50"]}, { //.....}]

也许还值得一提的是,每次我使用调试器(我使用 visual studio 代码)启动应用程序时,模拟器都会崩溃。这似乎是我的异步管道的问题,因为如果我从 html 代码中删除 | async,它会正常加载(显然我的屏幕上没有显示任何数据)。

我猜这是因为我在某处试图获取太多(无限?)数据,但我真的不知道。如果我稍后重新添加异步管道并保存文件,则调试器会重新加载应用程序并且 not 不会崩溃。

我不清楚到底是什么坏了,但是 sortFn$ 周围有一些 yellow/red 标记。您不应该将函数引用作为其初始值传递给它。我认为您可以通过执行以下操作来简化代码:

  • 将排序方法设置为 class 方法,而不是生成它并通过可观察流传递它。
  • 使用布尔流触发排序(默认为 false)。在视图中引用主题并点击调用下一个。

可能看起来像这样:

test.component.ts

export class TestComponent implements OnInit {
    propertyData : Test[] = [];
    sortedData$: Observable<Test[]>;
    sort$ = new BehaviorSubject<boolean>(false);

    constructor(private router: Router, private testService: TestService) {}

    ngOnInit() {
        this.sortedData$ = this.testService.getSurveyQuestion()
            .combineLatest(this.sort$)
            .map(([data, sort]: [Test[], boolean]) => {
                return sort ? data.sort(this.alphabeticalSort) : data;
            });
    }

    alphabeticalSort(a: Test, b: Test) {
        const aQ = a.question.toUpperCase();
        const bQ = b.question.toUpperCase();
        return aQ.localeCompare(bQ);
    }
}

test.component.html

<Label [text]="'Sort by alphabetical order'"(tap)="sort$.next(true)"></Label>
StackLayout *ngFor="let item of sortedData$ | async">
    <Label text="{{item.question}}"></Label>
</StackLayout>