私は Angular 2 と Ionic 2 を使用して、リアクティブ オブジェクトの配列を構築しようとしています。
サービス (StockService) からデータを取得する新しい監視可能な (Stock) クラス インスタンスをインスタンス化する単純なサービス (StocksListService) を介してそれ自体を生成するイオン リスト コンポーネント (StocksList) を構築する正しい方法を見つけようとしています。 Observable.interval で繰り返し API を呼び出します。
最終的には、Stocks[] を並べ替えるためのステートフル パイプを作成できるようにしたいと考えています (そして、自分が行っていることを行うための実際の正しい方法を理解したいと考えています)。
私の意図をそれ以上に簡潔に説明する方法が本当にわからないので、私のコードが状況を明確にするのに役立つことを願っています:
——</p>
ホームページ
^
株式一覧コンポーネント < 株式一覧サービス
^
株式コンポーネント < 株式サービス
——</p>
ホームページ—</p>
home.html
<ion-content>
<ion-list
stocksListCmp ></ion-list>
</ion-content>
home.ts
@Page({
templateUrl: 'build/pages/home/home.html',
directives: [StocksList],
providers: [StocksListService]
})
export class HomePage {
constructor(public nav: NavController) { }
}
株式リスト コンポーネント—</p>
stocks-list.tpl.html
<ion-card
[stockCmp]="stock"
*ngFor="#stock of stocks; #i = index"></ion-card>
stocks-list.component.ts
@Component({
selector: '[stocksListCmp]',
viewProviders: [StocksListService, StockService]
})
@View({
templateUrl: 'build/components/stocks-list/stocks-list.tpl.html',
directives: [Stock]
})
export class StocksList {
stocks: Observable<IStock>[]; // not sure if my typing is correct here, or anywhere with advanced types really
constructor(private stocksListService: StocksListService) { }
ngOnInit() {
this.stocks = this.stocksListService.stocks;
}
}
stocks-list.service.ts
let tickers: string[] = ['AAPL', 'BTCUSD=X', '^DJI', '^GSPC', 'NFLX', 'TSLA'];
@Injectable()
export class StocksListService {
constructor( @Inject(forwardRef(() => StockService)) private stockService: StockService) { }
get stocks(): Observable<IStock>[] {
return tickers
.map((ticker) => new Stock(this.stockService.init(ticker))); // getting type error on this.stockService.init(ticker): Observable<Observable<IStock>> not assignable to StockService
}
}
ストック コンポーネント—</p>
stock.tpl.html
<ion-card-content>
<ion-row>
<ion-col>{{ stock?.ticker }}</ion-col>
<ion-col>{{ stock?.price }}</ion-col>
<ion-col>{{ stock?.chg_percent}}</ion-col>
</ion-row>
</ion-card-content>
ストック.コンポーネント.ts
@Component({
selector: '[stockCmp]',
inputs: ['stockCmp'],
viewProviders: [StockService]
})
@View({
templateUrl: 'build/components/stock/stock.tpl.html'
})
export class Stock {
stockCmp: Stock; // not sure how to type here
stock: IStock; // not sure how to type here
constructor(private stockService: StockService) { }
ngOnInit() {
this.stockCmp['stockService']['init']
.subscribe((data) => this.stock = data,
null,
() =>
this.stockCmp['stockService']['update']
.subscribe((service) => service
.subscribe((data) => this.stock = data))
);
}
}
stock.service.ts
let source: Observable<number> = Observable.interval(60 * 1000).publish().refCount();
@Injectable()
export class StockService {
constructor(private http: Http) { }
public init(ticker: string): Observable<Observable<IStock>> {
if (ticker) {
let url = 'http://finance.yahoo.com/webservice/v1/symbols/' + ticker + '/quote?format=json&view=detail';
return this.updateData(url);
}
}
private loadData(url: string): Observable<IStock> {
return this.http.get(url)
.map((res) => this.mapData(res.json().list.resources[0].resource.fields));
}
private mapData(data: any): IStock {
return {
ticker: data.symbol,
name: data.name,
price: JSON.parse(data.price),
chg_percent: JSON.parse(data.chg_percent) / 100,
ts: data.ts
};
}
public updateData(url: string): Observable<Observable<IStock>> {
return { init: this.loadData(url), update: source.map(() => this.loadData(url)) }; // type error
}
private logError(error) {
console.log(error);
}
}
株式.d.ts
export interface IStock {
ticker: string;
name: string;
price: number;
chg_percent: number;
ts: number;
}
したがって、これは実際には現在かなりうまく機能していますが、正しい方法ではないことは確かです。最初の interval 呼び出しの前に loadData メソッドから結果を取得するためのより良い方法が必要です。
イオン リストの作成、新しいクラス インスタンスのインスタンス化、およびリアクティブ拡張の使用に関してこれを行う正しい方法を理解したいと思います。うまくいけば、株式リストを並べ替えるステートフル パイプを実装するのに役立ちます。
どんなアドバイスでも大歓迎です!何かを省略したり、明確にする必要がある場合は、お知らせください。ありがとう!