异步管道不显示来自可观察数据的数据

时间:2018-01-29 11:34:24

标签: typescript rxjs observable angular2-nativescript

昨天,我问了一个关于sorting nested observables的问题。不久之后,this answer指出了一个很好的总体方向。我设法“正确”将代码合并到我自己的项目中 - 也就是说,TypeScript没有给我任何错误。请参阅以下codesnippets:

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:全部:[{“问题”:“你的年龄范围是多少?”,“选项”:[“10-20”,“20-30”,“30-40”,“40-50”] },{//.....}]

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

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

1 个答案:

答案 0 :(得分:1)

我不清楚究竟是什么被打破,但sortFn$周围有一些黄色/红色标志。您不应该将函数引用作为其初始值传递给它。我认为您可以通过执行以下操作来简化代码:

  • 将排序方法设置为类方法,而不是生成它并将其传递给可观察的流。
  • 使用布尔流触发排序(默认为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>