本教程內(nèi)容和https://zhiwehu.gitbooks.io/react-native/content/ 同步更新。
篩選todo list
在本小節(jié)里,我們將在footer里增加幾個(gè)按鈕,用于篩選todo list,分別是顯示所有的todo,顯示沒有完成的todo以及顯示所有完成的todo。
在footer.js里,我們將導(dǎo)入TouchableOpacity來生成幾個(gè)按鈕。
// 定義Footer類,這個(gè)類是Component的子類
// 定義Footer類,這個(gè)類是Component的子類
class Footer extends Component {
/*
實(shí)現(xiàn)Header類的render方法,這個(gè)方法返回一個(gè)View,顯示Footer
*/
render() {
return (
<View style={styles.container}>
<View style={styles.filters}>
<TouchableOpacity style={styles.filter} onPress={() => this.props.onFilter('ALL')}>
<Text>全部</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.filter} onPress={() => this.props.onFilter('ACTIVE')}>
<Text>未完成</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.filter} onPress={() => this.props.onFilter('COMPLETE')}>
<Text>已完成</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
對(duì)于每個(gè)按鈕,我們會(huì)綁定onPress事件一個(gè)方法,和之前一樣,我們將不在footer.js里去實(shí)現(xiàn)這個(gè)方法,而是通過props從上層組件中傳遞進(jìn)來。
在app.js里,我們將來實(shí)現(xiàn)onPress事件上綁定的方法。
首先我們需要?jiǎng)?chuàng)建一個(gè)工具方法,這個(gè)工具方法將在很多地方通用,這個(gè)工具方法傳遞進(jìn)去2個(gè)參數(shù) :filter和todos,filter表示篩選條件,可以是ALL,ACTIVE或者是COMPLETE中的一個(gè)值,分別代表了全部,未完成以及全部完成的todo。todos表示需要進(jìn)行篩選的todo列表。
這個(gè)方法如下:
const filterItems = (filter, todos) => {
return todos.filter(todo => {
if (filter === 'ALL') return true;
if (filter === 'ACTIVE') return !todo.complete;
if (filter === 'COMPLETE') return todo.complete;
});
}
然后在App component里定義一個(gè)方法:
handleFilter(filter) {
this.setSource(this.state.items, filterItems(filter, this.state.items), {filter: filter})
}
這個(gè)方法非常簡(jiǎn)單,當(dāng)用戶點(diǎn)擊一個(gè)篩選條件的時(shí)候,將filter傳遞過來,使用我們上面定義的工具方法,得到篩選過后的列表,調(diào)用我們之前定義的 setSource方法,重新設(shè)置app.state的值,注意setSource第三參數(shù),我們需要將用戶這時(shí)的filter傳遞給app.state.filter,所以我們要在state里增加一個(gè)新的變量filter,默認(rèn)值是ALL。
// 初始化狀態(tài)
this.state = {
filter: "ALL",
value: "",
items: [],
dataSource: ds.cloneWithRows([])
};
接下來我們只需要在app.js里調(diào)用Footer組件里,將這個(gè)方法傳遞給Footer組件。
<Footer
onFilter = {this.handleFilter}
/>
別忘記在App的constructor方法里,使用
bind將handleFilter方法bind(this)
this.handleFilter = this.handleFilter.bind(this);
OK現(xiàn)在我們的filter已經(jīng)起作用了,但是經(jīng)過測(cè)試,我們發(fā)現(xiàn)當(dāng)你增加一個(gè)新todo,或者是刪除一個(gè)todo,或者是改變一個(gè)todo的狀態(tài)時(shí),我們的列表又重新顯示所有的數(shù)據(jù)了,為了解決這個(gè)問題,我們只需要在對(duì)應(yīng)的handleAddItem,handleRemoveItem以及handleToggleComplete這幾個(gè)方法里,對(duì)setSource方法里,調(diào)用我們的工具方法filterItems來篩選數(shù)據(jù)再傳給app.state。
this.setSource(newItems, filterItems(this.state.filter, newItems));
最后,我們將state.filter也傳給Footer組件,用于顯示當(dāng)前的filter是什么。
<Footer
filter = {this.state.filter}
onFilter = {this.handleFilter}
/>
在Footer組件里,可以使用this.props.filter來獲取當(dāng)前的filter,使用style來顯示一個(gè)外邊框,來突出顯示當(dāng)前選中的filter。
render() {
const {filter} = this.props;
return (
<View style={styles.container}>
<View style={styles.filters}>
<TouchableOpacity style={[styles.filter, filter === 'ALL' && styles.selected]} onPress={() => this.props.onFilter('ALL')}>
<Text>全部</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.filter, filter === 'ACTIVE' && styles.selected]} onPress={() => this.props.onFilter('ACTIVE')}>
<Text>未完成</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.filter, filter === 'COMPLETE' && styles.selected]} onPress={() => this.props.onFilter('COMPLETE')}>
<Text>已完成</Text>
</TouchableOpacity>
</View>
</View>
);
}
運(yùn)行結(jié)果如下。
