2016-10-12 4 views
0

Я работаю над reactjs with redux, чтобы создать приборную панель. Существует функциональность создания вкладки. Я мог бы создать вкладку и отправить rest api как POST, чтобы сохранить ее в базе данных, однако, как только нажата кнопка сохранения, вкладка также должна отображаться в заголовке, который сейчас не отображается. Также есть имя вкладки под названием dashboard (home), которое передается как начальное состояние, которое должно отображаться все время. Но только сохраненная вкладка отображается в заголовке, а также когда пользователь обновляет страницу не сразу, когда нажата кнопка сохранения.вкладка не отображается при добавлении

Короче говоря, созданная вкладка отображается, только когда пользователь обновляет страницу.

Помогите решить эту проблему?

действия

export function addTab(name, icon) { 
    return (dispatch) => { 
    dispatch({ type: 'POST_TAB_START' }); 
    return axios({ 
     method: 'POST', 
     url: '/rest-api/ui/tabs/', 
     headers: { 
     'X-CSRFToken': CSRF_TOKEN, 
     'Content-Type': 'application/json' 
     }, 
     data: { 
     name, 
     icon 
     }, 
    }) 
    .then((response) => { 
     dispatch({ type: 'POST_TAB', 
       payload: response.data }); 
    }) 
    .catch((err) => { 
     dispatch({ type: 'POST_TAB_FAILURE', payload: err }); 
    }); 
    }; 
} 

export function fetchTabs() { 
    return dispatch => { 
    axios.get('/rest-api/ui/tabs/') 
    .then((response) => { 
     dispatch({ type: 'RECIEVE_TAB', payload: response.data }); 
    }) 
    .catch((err) => { 
     dispatch({ type: 'FETCH_TAB_ERROR', payload: err }); 
    }); 
    }; 
} 

редукторы

const initial = { 
    posting: false, 
    posted: false, 
    tabs: [], 
    error: null 
}; 

export const postTab = (state = initial, action) => { 
    switch (action.type) { 
    case 'POST_TAB_START': 
     return { ...state, posting: false }; 
    case 'POST_TAB_FAILURE': 
     return { ...state, error: action.payload }; 
    case 'POST_TAB': 
     return { ...state, posting: false, posted: true, tabs: action.payload }; 
    default: 
     return state; 
    } 
}; 



const firstState = { 
    fetching: false, 
    fetched: true, 
    tabs: [ 
      { name: 'dashboard', id: 1, icon: 'dashboard' } 
     ], 
    error: null, 
}; 

export const fetchTab = (state = firstState, action) => { 
    switch (action.type) { 
    case 'RECIEVE_TAB': 
     return { ...state, fetching: false, fetched: true, tabs: action.payload }; 
    case 'FETCH_TAB_ERROR': 
     return { ...state, fetching: false, error: action.payload }; 
    default: 
     return state; 
    } 
}; 

Таб-dialog.js (здесь форма, чтобы сохранить закладку)

componentWillMount() { 
     this.props.fetchIcons(); 
     this.props.fetchTabs(); 
    } 

    onSubmit = (e) => { 
    e.preventDefault(); 
    this.props.addTab(this.state.name, this.state.icon); 
    } 

    renderAddTab() { {/* it is for adding tab from the dialog box */} 
    const listOfIcon = _.map(this.props.fetchIcon.icons, (icon) => ({ 
           text: icon.name, 
           id: icon.id, 
           value: <MenuItem primaryText={icon.name} /> 
         })); 
    return (
     <div className="device-action"> 
     <Dialog 
      title="Add a Tab" 
      modal={false} 
      bodyStyle={{ background: '#fff' }} 
      contentStyle={customContentStyle} 
      actionsContainerStyle={{ background: '#fff' }} 
      titleStyle={{ background: '#fff', color: '#1ab394' }} 
      open={this.props.createTab.open} 
      onRequestClose={this.props.closeTabIcon} 
     > 
     <form onSubmit={this.onSubmit}> 
     <div className="tab-name"> 
     <TextField 
      floatingLabelText="Name" 
      ref="name" 
      floatingLabelStyle={{ color: '#1ab394' }} 
      floatingLabelFocusStyle={{ color: '#1db4c2' }} 
      underlineStyle={{ borderColor: '#1ab394' }} 
      onChange={(name) => { this.setState({ name: name.target.value }); }} 
     /> 
     </div> 
     <div className="icon"> 
     <AutoComplete 
      floatingLabelText="select any icon" 
      ref="icon" 
      filter={AutoComplete.noFilter} 
      openOnFocus 
      dataSource={listOfIcon} 
      textFieldStyle={{ borderColor: '#1ab394' }} 
      className="autocomplete" 
      onNewRequest={(e) => { this.setState({ icon: e.id }); }} 
     /> 
     </div> 
     <button className="btn">Save</button> 
     </form> 
     </Dialog> 
     </div> 
); 
    } 

    render() { 
    const iconSelected = this.props.createTab; 
    if (!iconSelected) { 
     return (<span />); 
    } 
    if (iconSelected.id === '1') { 
     return (this.renderDeleteTab()); 
    } 
    if (iconSelected.id === '2') { 
     return (this.renderAddTab()); 
    } 
} 

header.js (здесь вкладка должна быть показана как только вкладка создается вместе с приборной панели вкладки по умолчанию)

class Header extends Component { 

    componentWillMount() { 
     this.props.fetchTabs(); 
    } 

    render() { 
    const tabs = _.map(this.props.fetchTab.tabs, (tab) => 
     <span className="tab" key={tab.id}><a href="">{tab.name}</a></span> 
    ); 

    const navigation = (
     <div className="nav-icon" style={{ margin: '12px 40px 0px 10px' }}> 
     <i 
      className="material-icons md-23" 
      id="1" 
      onClick={(event) => this.props.selectTabIcon(event)} 
     > 
      delete 
     </i> 
     <i 
      className="material-icons md-23" 
      id="2" 
      onClick={(event) => this.props.selectTabIcon(event)} 
     > 
      add_circle 
     </i> 
     </div> 
    ); 

    return (
     <div> 
     <AppBar 
      title={tabs} 
      iconElementRight={navigation} 
      onLeftIconButtonTouchTap={this.props.handleToggle} 
      style={{ background: '#fff' }} 
     /> 
     </div> 
    ); 
    } 
} 

enter image description here

ответ

0

Это переписав состояние tabs в fetchTab.

case 'RECIEVE_TAB': 
    return { ...state, fetching: false, fetched: true, tabs: action.payload }; 

Это делает его таким образом ваш { name: 'dashboard', id: 1, icon: 'dashboard' }, что вы создали в firstState переписывается, когда RECIEVE_TAB действие отправляется.

Вы, вероятно, хотите просто жесткий код его в JSX, если она есть всегда, но вы можете получить его предваряется на вкладку приборной панели:

const dashboardTab = { name: 'dashboard', id: 1, icon: 'dashboard' }; 

case 'RECIEVE_TAB': 
    return { 
    ...state, 
    fetching: false, 
    fetched: true, 
    tabs: [dashboardTab, ...action.payload] 
    }; 

Я не могу видеть, где в коде вы используют состояние postTab. Я собираюсь рисковать тем, что вам действительно просто нужно одно состояние с вкладками, и когда сообщение на сервере будет успешным, вы обновите то же самое состояние tab, которое будет извлечено?

Edit:

Ваш Header компонент делает вкладки в store.fetchTab.tabs, но при вызове функции addTab вы диспетчерская действие, которое обновляет другой объект в вашем штате, postTab.tabs. Вы, вероятно, просто хотите переделать форму своего государства.

редукторы

const dashboard = { name: 'dashboard', id: 1, icon: 'dashboard' }; 

const initalTabState = { 
    tabs: [dashboard], 
}; 

export const tabs = (state = initialTabState, action) => { 
    switch (action.type) { 
    case 'TABS_SET': 
     return { 
     ...state, 
     tabs: [dashboard, ...action.tabs], 
     }; 
    case 'TABS_ADD': 
     return { 
     ...state, 
     tabs: [...state.tabs, action.tab], 
     }; 
    case 'TABS_RESET': 
     return { 
     ...initalTabState, 
     }; 
    default: 
     return state; 
    } 
}; 

const initalTabsPostState = { 
    posting: false, 
    posted: false, 
    error: null, 
}; 

export const tabsPost = (state = initialTabsPostState, action) => { 
    switch (action.type) { 
    case 'TABS_POST_START': 
     return { 
     ...initialTabsPostState, 
     posting: true, 
     }; 
    case 'TABS_POST_SUCCESS': 
     return { 
     ...initialTabsPostState, 
     posted: true, 
     }; 
    case 'TABS_POST_FAILURE': 
     return { 
     ...initialTabsPostState, 
     error: action.payload, 
     }; 
    default: 
     return state; 
    } 
}; 

const initialTabsFetchState = { 
    fetching: false, 
    fetched: true, 
    error: null, 
}; 


export const tabsFetch = (state = initialTabsFetchState, action) => { 
    switch (action.type) { 
    case 'TABS_FETCH_START': 
     return { 
     ...initialTabsFetchState, 
     fetching: true, 
     }; 
    case 'TABS_FETCH_SUCCESS': 
     return { 
     ...initialTabsFetchState, 
     fetched: true, 
     }; 
    case 'TABS_FETCH_FAILURE': 
     return { 
     ...initialTabsFetchState, 
     error: action.payload, 
     }; 
    default: 
     return state; 
    } 
}; 

действия

export function addTab(name, icon) { 
    return (dispatch) => { 
    dispatch({ type: 'TABS_POST_START' }); 
    return axios({ 
     method: 'POST', 
     url: '/rest-api/ui/tabs/', 
     headers: { 
     'X-CSRFToken': CSRF_TOKEN, 
     'Content-Type': 'application/json' 
     }, 
     data: { 
     name, 
     icon 
     }, 
    }) 
    .then((response) => { 
     dispatch({ type: 'TABS_POST_SUCCESS' }); 
     dispatch({ type: 'TABS_ADD', tab: response.data }); 
    }) 
    .catch((err) => { 
     dispatch({ type: 'TABS_POST_FAILURE', payload: err }); 
    }); 
    }; 
} 

export function fetchTabs() { 
    return (dispatch) => { 
    dispatch({ type: 'TABS_FETCH_START' }); 
    return axios.get('/rest-api/ui/tabs/') 
     .then((response) => { 
     dispatch({ type: 'TABS_FETCH_SUCCESS' }) 
     dispatch({ type: 'TABS_SET', tabs: response.data }); 
     }) 
     .catch((err) => { 
     dispatch({ type: 'TABS_FETCH_FAILURE', payload: err }); 
     }); 
    }; 
} 
+0

спасибо за решение для демонстрации вкладки приборной панели. Что касается вкладки, которая будет отображаться сразу после создания вкладки, функция tabChange и функция onSubmit будут использоваться в tab-dialog.js. Я использовал состояние fetchTab, чтобы показать вкладку, как только пользователь ее создаст. – milan

+0

Да, когда пользователь отправляется на сервер, я хочу обновить ту же вкладку и извлечь ее. Например, для каждого пользователя будет отображаться одна вкладка, которая не может быть отредактирована или удалена. Теперь пользователь хочет добавить еще одну вкладку, например вкладку с названием коммерческих устройств, после чего они перейдут на вкладку добавления и создадут название вкладки, называемое коммерческими устройствами, и как только они отправятся на сервер, рекламная кампания должна быть показана вместе с вкладками dasboard и предыдущими добавленными вкладками Если там есть. – milan

+0

Я понимаю редуктор столбца и действия. Но я не понял функцию табуляции. Какая польза от этого, когда уже есть tabsFetch()? Почему 2 функции редуктора используются вкладками и вкладкамиFetch()? – milan

Смежные вопросы