编者语:前三篇的文章把React的基础和TypeScript对ReactJS的一些整合方式都介绍给大家了,接下来几篇会聊到如何和数据业务进行整合。今天先说说简单的数据整合,而之后会说flux。
好我们先来看看代码(话说代码大家都是比较关注的),继续我们之前的例子,需要加载数据的是CatalogList这个组件,所以我们把焦点放在这里。
1. 先做好一个DataService.ts , 这里我用到了jquery 和 bluebird
2. 我们需要对之前的CatalogList 和 CatalogItem 做对应调整,由于我们需要在CatalogList上加载数据,所以我们需要定义它的State值,而在CatalogItem中我们只需要把CatalogList中加载数据后的每一项数据传递给CatalogItem的Props即可。
先看我们定义的CatalogItem , 这里我们定义了一个接收数据的Props , 注意一点在ReactJS中初始化getInistailState在TypeScript中的呈现方式是用构造函数所取代的,而参数值传递是以{}作为标签,根据接口的数据,就有了我们下列的呈现方式
3. 运行后你就可以看结果了(图片就不在这里加载了)
数据加载现在在JS 上都会使用Promise的模式(http://www.infoq.com/cn/news/2011/09/js-promise) , 而React 对于数据的载入重点不是你用什么方法去利用Promise模式去加载数据。更多是关心你的数据是怎么触发数据页面的DOM元素的变化。在该系列文章的第二篇也有提及几个名JSX, State,Props都是React中数据加载后影响的几个元素。
我们来看看State变化时的一些细节,触发DOM元素的变化是在ComponnetDidUpdate()方法内,这里通过SetState去触发重新的render()
好我们先来看看代码(话说代码大家都是比较关注的),继续我们之前的例子,需要加载数据的是CatalogList这个组件,所以我们把焦点放在这里。
1. 先做好一个DataService.ts , 这里我用到了jquery 和 bluebird
///<reference path="../typings/jquery/jquery.d.ts" />
///<reference path="../typings/bluebird/bluebird.d.ts" />
module ReactDemo.Utils
{
export class DataService{
getCatalogList() : Promise<string>{
var url = '/api/values';
return this.getPromise(url);
}
private getPromise(api: string): Promise<string> {
return new Promise((resolve: (result: string) => void, reject: (error: string) => void): void => {
$.ajax(<JQueryAjaxSettings>{
url: api,
cache: false,
dataType: "json",
type: "GET",
success: resolve.bind(this),
error: (jqXHR: JQueryXHR, status: string, message: string) => {
reject(`status[${status}] message[${message}]`);
}
});
});
}
}
}
2. 我们需要对之前的CatalogList 和 CatalogItem 做对应调整,由于我们需要在CatalogList上加载数据,所以我们需要定义它的State值,而在CatalogItem中我们只需要把CatalogList中加载数据后的每一项数据传递给CatalogItem的Props即可。
先看我们定义的CatalogItem , 这里我们定义了一个接收数据的Props , 注意一点在ReactJS中初始化getInistailState在TypeScript中的呈现方式是用构造函数所取代的,而参数值传递是以{}作为标签,根据接口的数据,就有了我们下列的呈现方式
interface CatalogItemProps {
data : any;
}
class CatalogItem extends React.Component<CatalogItemProps,any>{
constructor(props : CatalogItemProps){
super(props);
}
public render()
{
return (<div>
<div className="goods">
<a href="#">
<div className="goods-img">
<img src="images/goods/good.jpg" alt="" />
<span className="goods-mark">
<span className="goods-discount">{this.props.data.catalogGroupPrice}折</span>
<span className="customers-num">{this.props.data.catalogGroup}人团</span>
</span>
</div>
<h2>{this.props.data.catalogName}</h2>
<p className="outline">{this.props.data.catalogIntro}</p>
<div className="goods-go">
<div className="goods-go-icon"></div>
<div className="goods-go-price">
<span>{this.props.data.catalogGroup}人团</span>
<b>¥{this.props.data.catalogGroupPrice}</b>
</div>
<div className="goods-go-btn">去开团</div>
</div>
</a>
</div>
</div>);
}
}
而CatalogList 如下:
interface CatalogListState {
list : any ;
}
interface CatalogListProps {
}
class CatalogList extends React.Component<CatalogListProps,CatalogListState>{
public state : CatalogListState ;
constructor(props : CatalogListProps){
super(props);
this.state = {list : []};
}
public componentDidMount: () => void =
(): void => {
var dataService = new ReactDemo.Utils.DataService();
var dataList;
dataService.getCatalogList().then((result:string)=>{
this.setState({list:result});
});
}
public render()
{
var catalogs;
if(this.state.list){
catalogs = this.state.list.map(function(catalog){
return (<div>
<CatalogItem data={catalog}/>
</div>);
});
}
return (<div>
<div id="goods-list">
{catalogs}
</div>
</div>);
}
}
关于CatalogList需要注意的地方是你必须判断state中list是否有效否则会出错,所以if(this.state)是不能缺少的,否则出错,其次不要忘记componentDidMount才能触发this.setState(....)
3. 运行后你就可以看结果了(图片就不在这里加载了)
好就说到这里,明天我们谈flux