Moment For Technology

React Technology Stack + Express Front-end and back-end blog project (9) -- Post function on the front-end management interface + corresponding back-end interface

Posted on Sept. 23, 2022, 1:37 p.m. by Dr. Lawrence O'Brien
Category: The front end Tag: react.js The front end The back-end express

Project Address:Github.com/Nealyang/Re...

I wanted to serialize a series of blogs after the completion of the project, but as the development went on, I did meet many pits and consulted many people. So I thought, why not share the harvest while recording the pits. Sharing is good, of course, but it would be even more beautiful if we could pool our ideas. Our slogan is: never lose the tail

This blog for serial code blog synchronous update blog, with the future development of the project may encounter in front of the inappropriate place will be revised back. If there is anything wrong ~ welcome brothers don't add to your comments. Thank you very much!

Results demonstrate

  • Results show

  • Database Screenshot

Back-end partial implementation

Article content initially contains the following fields: article title, article content, author, article tag, number of views, number of comments, publication time, whether to publish

So define the schema as follows:

Import mongoose from 'mongoose' module.exports = new mongoose.Schema({title:String,// ViewCount :Number,// commentCount:Number,// commentCount:Number,// commentCount time:String,// published time coverImg:String,// Cover image author:String,// Author Tags :Array,// tags isPublish:Boolean// Whether publish});Copy the code

Backend post interface development is actually a storage interface, preliminary interface design for/API/admin/article/addArticle

router.post('/addArticle', function (req, res) { const { title, content, time, tags, isPublish } = req.body; const author = req.session.userInfo.username; const coverImg = `/${Math.round(Math.random() * 9 + 1)}.jpg`; const viewCount = 0; const commentCount = 0; let tempArticle = new Article({ title, content, isPublish, viewCount, commentCount, time, author, coverImg, tags }); Temparticle.save ().then(data={responseClient(res,200,0,' saved successfully ',data)}).cancel(err={console.log(err); responseClient(res); }); });Copy the code

The back end is more general. For routing design and model we can view the source code

The front part

Interface coding:

Render () {return (div h2 post /h2 div className={style.container} span className={style.subtitle} title /span Input className={style.titleInput} placeholder={type='text' value={this.props. Title} OnChange ={this.titleonchange.bind (this)}/ span className={style.subtitle} /span textarea className={style.textArea} value={this.props.content} onChange={this.onChanges.bind(this)}/ span ClassName ={style.titleInput} placeholder= {className={style.titleInput} placeholder= {className={style.titleInput} placeholder= { onChange={this.selectTags.bind(this)} defaultValue={this.props.tags}  { this.props.tagsBase.map((item) = { return ( Option key={item}{item}/Option ) }) } /Select div className={style.bottomContainer} Button type="primary" OnClick ={this.publisharticle.bind (this)} className={style.buttonstyle} /Button Button type="primary" OnClick ={this.savearticle.bind (this)} className={style.buttonstyle} Save /Button Button type="primary" OnClick ={this.preview.bind (this)} className={style.buttonstyle} preView /Button /div /div Modal OnOk ={this.handleok.bind (this)} width={'900px'} onCancel={this.handleOk.bind(this)} footer={null}  div className={style.modalContainer} div id='preview' className={style.testCode} {remark().use(reactRenderer).processSync(this.props.content).contents} /div /div /Modal /div ) }Copy the code

Defined as a technical blog, we only support the MD syntax here. Use remark-react to convert the MD syntax. TextArea as input field. There is currently no support for uploading images. If you want to support image uploads, check out my other demo on Github. I'm not going to do the demo here.

State design of the front part

For the post part, I store title,tags and content separately. To make it easier for users to switch to other menu items when writing general articles. So store it in state. Update state directly when typing title,content,tags in input. This way, when the user switches to another TAB and back, the user can still see what he entered.

const initialState={ title:'', content:'', tags:[] }; export const actionTypes = { UPDATING_TITLE:"UPDATING_TITLE", UPDATING_CONTENT:"UPDATING_CONTENT", UPDATING_TAGS:"UPDATING_TAGS", SAVE_ARTICLE:"SAVE_ARTICLE" }; export const actions = { update_title:function (title) { return{ type:actionTypes.UPDATING_TITLE, title } }, update_content:function (content) { return{ type:actionTypes.UPDATING_CONTENT, content } }, update_tags:function (tags) { return{ type:actionTypes.UPDATING_TAGS, tags } }, save_article:function (data) { return{ type:actionTypes.SAVE_ARTICLE, data } } }; export function reducer(state=initialState,action) { switch (action.type){ case actionTypes.UPDATING_TITLE: return{ ... state,title:action.title }; case actionTypes.UPDATING_CONTENT: return{ ... state,content:action.content }; case actionTypes.UPDATING_TAGS: return{ ... state,tags:action.tags }; default: return state; }}Copy the code

Front-end Saga

In Saga, we need to determine whether the user should save or publish. So we added the isPublish field to differentiate. There are some required fields that we need to judge when publishing.

export function* saveArticleFlow () { while (true){ let request = yield take(NewArticleActionTypes.SAVE_ARTICLE); console.log(request); if(request.data.isPublish){ if(request.data.title === ''){ yield put({type: IndexActionTypes.SET_MESSAGE, msgContent: 'Please enter article title ', msgType: 0}); }else if(request.data.content === ""){yield put({type: indexactiontypes.set_message, msgContent: 'Please enter the content of the article ', msgContent: 0}); }else if(request.data.tags.length === 0){ yield put({type: IndexActionTypes.SET_MESSAGE, msgContent: 'Please select article category ', msgType: 0}); } } if((request.data.titlerequest.data.contentrequest.data.tags.length0request.data.isPublish)|| (! request.data.isPublish)){ let res = yield call(saveArticle,request.data); if(res){ if (res.code === 0) { yield put({type: IndexActionTypes.SET_MESSAGE, msgContent: res.message, msgType: 1}); setTimeout(function () { location.replace('/admin/managerArticle'); }, 1000); } else if (res.message === 'id has expired, please log in again ') {yield put({type: indexactiontypes.set_message, msgContent: res.message, msgType: 0}); setTimeout(function () { location.replace('/'); }, 1000); } else { yield put({type: IndexActionTypes.SET_MESSAGE, msgContent: res.message, msgType: 0}); } } } } }Copy the code

When the article is published successfully, we will jump to the article management interface after a given second. Since the management interface is not developed at present, it will be 404 after jumping to the management interface. In the next article, we'll cover feature development for the article administration section.

The article preview

The preview of the article, directly use ANTD modal, and then convert MD syntax, show the effect.

conclusion

Generally speaking, the article is also relatively simple to publish. I want you to think about the details. At this point, the core function of a blog site is complete.

Project implementation steps series blog

Study and communication

Welcome to pay attention to personal wechat official account: Nealyang full stack front, get the first-hand article push and free full stack ebook sharing benefits

Search
About
mo4tech.com (Moment For Technology) is a global community with thousands techies from across the global hang out!Passionate technologists, be it gadget freaks, tech enthusiasts, coders, technopreneurs, or CIOs, you would find them all here.