3

私の Angular 2 アプリでは、適切なアプリを開始する前に、多数の SVG をロードすることから始めたいと考えています。これを行うには、まずサーバーから svg の場所のリストを読み込み、次にそれぞれを順番にフェッチします。

AppComponent に 'loading' プロパティがあり、ロード中のテキストを表示/非表示にするためにいくつかの ngIf を制御しています。問題は、svg がすべて読み込まれると、Angular が AppComponent のバインディングを更新しないことです。

どうしてこれなの?ゾーンがこれを処理すると思いましたか?

SvgLoader

import {Injectable, Output, EventEmitter, NgZone} from 'angular2/core';
import {Http, Response} from 'angular2/http';
import 'rxjs/Rx';
import {Observable} from 'rxjs/Observable';

const SVG_LIST:string = 'svg/list.json';

@Injectable()
export class SvgLoader {
    @Output() state: EventEmitter<string> = new EventEmitter();

    private svgs:{[file:string]:string};

    constructor(private http:Http){
        this.svgs = {};
    }

    getSvg(path:string):string {
        return this.svgs[path];
    }

    load():void {
        this.http.get(SVG_LIST)
            .map(res => {
                return <Array<string>> res.json().files;
            })
            .flatMap((files) => Observable.forkJoin(files.map(file => {
                return this.http.get('svg/' + file);
            })))
            .catch(this.handleError)
            .mergeAll()
            .subscribe(
                res => {
                    let index = res.url.indexOf('svg');
                    let path = res.url.substring(index);
                    this.svgs[path] = res.text();
                },
                error => console.error(error),
                () => {
                    this.state.emit('loaded');
                }
            );
    }

    private handleError(error:Response) {
        console.error(error);
        return Observable.throw(error.json().error || 'Server error');
    }
}

AppComponent

export class AppComponent {

    // On start, list the game sessions
    private state:string;
    public loading:boolean;

    constructor(private svgLoader:SvgLoader){
        this.loading = true;
        this.state = 'joining';
    }

    ngOnInit():void {
        this.svgLoader.state.subscribe(this.loaded);
        this.svgLoader.load();
    }

    loaded():void {
        console.log('loaded');
        this.loading = false;
    }
}

テンプレート

<div>
    <h1 *ngIf="loading">Loading...</h1>


    <div *ngIf="!loading">
         Loaded
    </div>
</div>
4

0 に答える 0