异步管道不显示来自 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>
昨天,我问了一个关于
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>