回來面對囉 雖然說是面對 不過是應該說 把之前做的完整說一下
OK 講一下大概要做什麼
我們先看一下我最後的成果樣子
這個是外側的選單
再來是打開可以選擇的公司名單
簡單說 這裡考慮到幾項事情
export const GetAllCompMember = (_compid, _userid, _token) => {
var formData = new FormData();
formData.append("token", _token);
formData.append("CompID", _compid);
return (dispatch) => {
fetch("http://xx.xxx.xxx/user/get_comp_all_member", {
method: "POST",
body: formData
})
.then(function(response) {
return response.json();
})
.then(function(jsonData) {
let _currentUser = jsonData.data.filter(function(_ele) {
return _ele.UserID == _userid;
});
dispatch({
type: Insert_All_Comp_Member,
payload: {
AllCompUser: jsonData.data
}
});
dispatch({
type: Update_Current_User_Name,
payload: {
CurrentUser: _currentUser[0]
}
});
})
.catch(function(e) {
console.log(e);
})
}
};
這一段主要就是拉回所有成員 並在同時更新 我目前這個登入者的名稱 讓他顯示出來
看完 Action 接下來看一下 container 連接什麼東西
export default connect(
// 從這裡把State的狀態值抽出來,然後component那邊就可以用this.props.Email 把它放在function 當成參數來傳
(state) => ({
Token: state.getIn(['InitReducer', 'Token']),
CompID: state.getIn(['InitReducer', 'CurrentUser', 'CompID']),
UserID: state.getIn(['InitReducer', 'CurrentUser', 'UserID']),
LastName: state.getIn(['InitReducer', 'CurrentUser', 'LastName']),
FirstName: state.getIn(['InitReducer', 'CurrentUser', 'FirstName']),
CompName: state.getIn(['InitReducer', 'CurrentComp', 'ShortName']),
然後 component view 的部分
OK 這樣做完 就可以簡單看到你這個人的人名
But 這滿無聊的 沒什麼特別
比較有趣的是我們用 semantic Ui Modal 來做 可以切換公司的部分
第一 先把資料拉出來
export const GetUserAccessComps = (_compid, _userid, _token) => {
var formData = new FormData();
formData.append("token", _token);
formData.append("UserID", _userid);
return (dispatch) => {
fetch("http://xxx.xxx.xxx/api/comp/get_user_access_comps", {
method: "POST",
body: formData
})
.then(function(response) {
return response.json();
})
.then(function(jsonData) {
let _currentComp = jsonData.data.filter(function(_ele) {
return _ele.CompID == _compid
})[0].company_info;
// 設定當前要的公司資料
dispatch({
type: Update_Current_Comp,
payload: {
CurrentComps: _currentComp[0]
}
});
// 寫入目前使用者可以進入的公司
dispatch({
type: Insert_User_Access_Comp,
payload: {
AllComps: jsonData.data
}
});
})
.catch(function(e) {
console.log(e);
})
}
};
再來去 redux的model 設定好你要哪些東西 長什麼樣子
export const InitUserData = Immutable.fromJS({
// 其他測試資料
'CompData': {
id: '',
name: '4',
},
'CompList': [{
id: '123',
name: '123'
}],
// 正式資料
'CurrentUser': {
CompID: '',
UserID: '',
LastName: '',
FirstName: ''
},
Email: "",
Password: "",
IsLogin: false,
Token: '',
// 公司裡面現有的成員
'AllCompMember': [],
// 控制是否開啟切換多公司畫面
companyModalOpen: false,
// 可以進入的公司列表
'AllComps': [{
CompID: '',
ShortName: '',
TimeZone: '',
IsActive: '',
LogoPath: ''
}],
..........
}),
接著 container 要把redux tree store 起來的值 傳進 component
// 從這裡把State的狀態值抽出來,然後component那邊就可以用this.props.Email 把它放在function 當成參數來傳
(state) => ({
Token: state.getIn(['InitReducer', 'Token']),
CompID: state.getIn(['InitReducer', 'CurrentUser', 'CompID']),
UserID: state.getIn(['InitReducer', 'CurrentUser', 'UserID']),
LastName: state.getIn(['InitReducer', 'CurrentUser', 'LastName']),
FirstName: state.getIn(['InitReducer', 'CurrentUser', 'FirstName']),
CompName: state.getIn(['InitReducer', 'CurrentComp', 'ShortName']),
AllComps: state.getIn(['InitReducer', 'AllComps']),
companyModalOpen: state.getIn(['InitReducer', 'companyModalOpen']),
並定義兩個方法
一個是打開切換的頁面
一個是選擇公司的動作
(dispatch) => ({
onEnterInComp: (_compItem, _userid, _token) => () => {
dispatch(ChangeCurrentComp(_compItem, _userid, _token))
dispatch(GetUserAccessDiscs(_compItem.get('CompID'), _userid, _token))
},
onChangeIsOpenCompModal: (_isopen) => () => (
dispatch(ChangeIsOpenCompModal(_isopen))
)
}),
最後 來看 component 這個裡面有些特別的
<div >
<img src={require('../../images/Logo/458.jpg')}
style={styles.compLogo}/>
<span style={{...styles.compName, ...styles.TextLimitation}}>{this.props.CompName}</span>
<Modal
trigger={<Button onClick={this.props.onChangeIsOpenCompModal(true)} color="blue" style={{...styles.switchBtn, ...styles.TextLimitation}}>{t('SwitchCompany')}</Button>}
open={this.props.companyModalOpen}
onClose={this.props.onChangeIsOpenCompModal(false)}
basic
size='fullscreen'>
<Header icon='browser' content='切換公司' />
<Modal.Content scrolling>
<div>
<Grid>
{this.props.AllComps.map(function(_item, _key)
{
return (
<Grid.Column mobile={16} tablet={8} computer={4} key={_key}>
<div style={styles.switchComp.wrap}>
<div style={styles.switchComp.side}>
<Image style={styles.switchComp.logo}
src={require('../../images/companyLogo/Default_Company0.jpg')}
onClick={this.props.onEnterInComp(_item, this.props.UserID, this.props.Token)}>
</Image>
</div>
<div style={{...styles.switchComp.side, ...styles.switchComp.rightside}}>
<span style={{...styles.switchComp.name, ...styles.TextLimitation}}
onClick={this.props.onEnterInComp(_item, this.props.UserID, this.props.Token)}>
{_item.get('ShortName')}
</span>
<label style={styles.switchComp.noreadNum}>0</label>
<p style={styles.switchComp.leaveCompText}>{t('ExitCompany')}</p>
</div>
</div>
</Grid.Column>
)
}, this)}
</Grid>
</div>
</Modal.Content>
<Modal.Actions>
<Button color='green' onClick={this.props.onChangeIsOpenCompModal(false)} inverted>
<Icon name='checkmark' /> 關閉
</Button>
</Modal.Actions>
</Modal>
</div>
一般 查得到資料的 我就不解釋了
比較特別是 如果你從 action 做 fetch 然後把一個 array 放進去 store 後
你再拉出來 他會變成一個 list 並不會是 array
所以這時候 你用map的方法 可以繞他
但是你再取值的時候要注意用 {item.get('YOUR PARAM NAME')}
然後
{this.props.AllComps.map(function(_item, _key){}, this)}
這個 ,this
很重要 如果沒有他 你裡面就沒有辦法去做 container 裡面方法的呼叫
後面我們還有 討論組列表 render 的互動 這個請看 Day16