我正在使用 Angular 2 和 Ionic 2,试图构建一系列反应对象。
我试图找出正确的方法来构建一个离子列表组件(StocksList),该组件通过一个简单的服务(StocksListService)来填充自己,该服务实例化新的可观察(Stock)类实例,这些实例从服务(StockService)获取数据在 Observable.interval 上重复调用 API。
最终,我希望能够创建一个有状态的管道来对 Stocks[] 进行排序(并且我想了解实际正确的方法来做我正在做的事情)。
我真的不知道如何更简洁地解释我的意图,所以我希望我的代码能帮助澄清情况:
——</p>
首页
^
股票列表组件 < 股票列表服务
^
股票组件 < 股票服务
——</p>
主页——</p>
主页.html
<ion-content>
<ion-list
stocksListCmp ></ion-list>
</ion-content>
主页.ts
@Page({
templateUrl: 'build/pages/home/home.html',
directives: [StocksList],
providers: [StocksListService]
})
export class HomePage {
constructor(public nav: NavController) { }
}
股票列表组件—</p>
股票-list.tpl.html
<ion-card
[stockCmp]="stock"
*ngFor="#stock of stocks; #i = index"></ion-card>
股票列表.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;
}
}
股票-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>
stock.component.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;
}
所以这实际上现在工作得很好,但我确信这不是正确的方法。在第一次间隔调用之前,必须有更好的方法从 loadData 方法中获取结果。
我想了解在构建离子列表、实例化新类实例和使用响应式扩展方面的正确方法,希望这将帮助我实现一个有状态的管道来对股票列表进行排序。
非常感谢任何建议!如果我遗漏了任何内容或需要澄清任何内容,请告诉我。谢谢!