--- tags: N108 Component --- # ExamWrapper.jsx - component 切換流程圖 - 可以配合 PPT 17頁 ```graphviz digraph Pageswitch { nodesep=0.8 node [color=orange, fontsize=22, shape=box] edge [color=RosyBrown, style=dashed] Exam->{Contain Wrapper} Wrapper->{ProblemImg Choosebtn Issue} Wrapper [color=orange, fontsize=22, shape=box,style=filled, fillcolor=Bisque] } ``` ## import 資料 | 名稱 | 類型 | 描述 | 來源 | | :------ | :----------- | :----------- | :----------- | | NavLink | <font color='RosyBrown'>external component</font> | Route | react-router-dom | | api | <font color='Green'>function</font> | API function | app/lib/api.js | | ChooseBtn | <font color='BlueViolet'>component</font> | 每個題目的選項 component | exam/ExamChoosebtn.jsx | | Problem_img | <font color='BlueViolet'>component</font> | 每個題目的圖片容器 component | exam/ExamProblemImg.jsx | | Detail | <font color='BlueViolet'>component</font> | 詳解頁面| detail/Detail.jsxx | | Issue | <font color='BlueViolet'>component</font> | 詳解頁面| exam/ExamIssue.jsx | | collectform | <font color='Green'>function</font> | 獲取form 資料 | app/lib/collectform.jsx | | queryString | <font color='Green'>function</font> | query-string 擷取函數 | query-string | | sorry | <font color='Red'>image</font> | 抱歉圖片 | image/sorry.png | | Cbtn | <font color='BlueViolet'>component</font> | wrapper close button | tool/Closebtn.jsx | ## constructor 介紹 ### state 參數介紹 | 名稱 | 類型 | 描述 | defalut | | :------ | :----------- | :----------- | :-- | | `data` | <font color='Gold'>json value</font> | API 傳回的題目資料| `[]` | | `ansset` | <font color='Gold'>json value</font> | 每個題目的正確解答| `[]` | | `inputSet` | <font color='orange'>string array</font> | 每個題目的狀態 (對 or 錯)|`[]`| | `myAns` | <font color='Gold'>json value</font> | 使用者回答題目的答案| `[]` | | `submit` | <font color='blue'>bool</font> | 使用者繳交答案,終止考試| `false` | | `problemId` | <font color='Salmon'>int</font> | 目前在第幾題對應的 ID| `0` | | `error` | <font color='orange'>string</font> | API 傳回的錯誤訊息|`null`| | `isLoaded` | <font color='blue'>bool</font> | API loading,true 為 loading 完成,false 為正在 loading | `false` | | `cid` | <font color='Salmon'>int</font> | 考卷對應的 CID| `0` | ### this.answer - React.createRef 輸入用 ## componentDidMount 1. queryString 擷取 cid 2. 執行 get_api(),並將 isLoaded = true 和 cid 存入 state 3. 有成功登入時,增加監聽事件 keydown (偵測 f5 按下提醒) ## componentDidUpdate - 當 prevState == this.state 時,執行 get_api(),並將 isLoaded = true、submit = false、problemId = 0 ## componentWillUnmount - 有成功登入時,刪除監聽事件 keydown (偵測 f5 按下提醒) ## 獨立 function | 名稱 | 描述 | async 是否 | |:--|:--|:--| |get_api()|Call API,並將資料分類存入 state|是| |f5check()|偵測 f5 有沒有按下,有按下時,系統給予提醒|否| |getstr()|考題圖片 NamePath 後處理,~~又是一個不在後端處理的案例~~|否| |problemList()|建立圖片列表 div,包含:選項、題目圖片、Issue 按鈕|否| |submit()|繳交,*介紹在下方*|否| |nextP()|下一題的 button event function,如果沒有選擇選項則會提醒沒有選擇答案|否| |backP()|上一題的 button event function|否| |resetproblem()|重新設定考試相關參數 (回到第一題),reset 功能|否| |gotohome()|回首頁 function|否| ### submit() 介紹 - 獲取使用者點選答案 ```jsx=128 let formitems = collectform(this.answer.current) var writed = Object.getOwnPropertyNames(formitems)[this.state.problemId] ``` - 如果沒選擇答案,不能 submit ```jsx=130 if (typeof (writed) == "undefined") alert('請選擇答案!!!') ``` - 對答案 ```jsx=133 let myAns = Object.getOwnPropertyNames(formitems).slice() //使用者解答 let YorN = [] for (var i = 0; i < myAns.length; i++) { if (myAns[i][1] == this.state.ansset[parseInt(myAns[i], 10)]) //判斷對錯 YorN.push("yes") else YorN.push("no") } ``` - 確定繳交才更新 state 資料 ```jsx=142 var yes = confirm('你確定要繳交嗎?') if (yes) { this.setState({ myAns: myAns.slice(), inputSet: YorN.slice(), submit: true }); } ``` ## API 數量表格 | 名稱 | 類型 | 描述 | 位於 | |:--|:--|:--|:--| |Exam/img_path?cid= + <font color='Blue'>cid</font>|<font color='LightSkyBlue'>get</font>|獲取該考卷所有的題目圖片 path,且答案額外抓出來一起存入 state|get_api()| ## render ### props (上層傳入) 參數介紹 | 名稱 | 類型 | 描述 | | :------ | :----------- | :----------- | | `login` | <font color='blue'>bool</font> | 登入參數,true 為登入中;false 為沒登入(訪客) | ### 額外參數 | 名稱 | 類型 | 描述 | | :------ | :----------- | :----------- | | `problemList` | <font color='OrangeRed'>HTML</font> | this.problemList(data) | - 大概長這樣 - [ExamProblemImg.jsx](https://hackmd.io/TDvYaVb4Rxmsle1jHHhseA?view) - [ExamChoosebtn.jsx](https://hackmd.io/NHFUFxXIRJCOOMtPWLvENQ?view) - [ExamIssue.jsx](https://hackmd.io/jVrW4AnjR2i9zXk93EDWuw?view) ```jsx=111 problemlist.push( <div className={`problem-containter ${this.state.problemId == i ? "" : "dis-no"}`} key={data[i].pid}> <Problem_img str={str}></Problem_img> <ChooseBtn id={i} answer={this.answer}></ChooseBtn> <Issue pid={data[i].pid} get_api_img={this.get_api} ></Issue> </div> ) ``` ### return - 如果登入成功、沒按繳交、cid != 0 (queryString 有讀到),都會顯示考試畫面 - 底下 HTML 太多不介紹,只說明條件 ```jsx=212 login && !submit && cid != 0 && ``` - 最後一題時,才會顯示 Submit button ```jsx=216 {problemId == problemList.length - 1 && ``` - 第一題時,不顯示 back (上一題) button ```jsx=224 {problemId != 0 && ``` - 非最後一題時,都會顯示 next (上一題) button,最後一題時,顯示 Submit button ```jsx=224 {problemId != problemList.length - 1 && ``` - submit之後,顯示解答跟詳解 ➡️ [Detail.jsx](https://hackmd.io/FtBVORlmQSC-1fIoqoSa6A?view) ```jsx=237 { login && submit && <Detail data={data} getstr={this.getstr} ans={inputSet} myans={myAns} ansset={ansset} f5check={this.f5check}> </Detail> } ``` - 沒登入的畫面 -  - 純 HTML 不介紹 ```jsx=244 { !login && <div className="dis-center" style={{ "height": "calc(80vh)" }}> <div className="help-map dis-center"> <div className="help-content"> <div className="help-header"> <Cbtn Clickbtn={this.gotohome}></Cbtn> <h4 className="help-title" id="mySmallModalLabel"> <i className="fa fa-warning"></i>  Warning </h4> </div> <div className="help-body dis-center2 animate-top"> <div> <div className="dis-center"><div style={{ "fontSize": "25px" }}>請登入才能開啟評測功能!</div></div> <img src={sorry} alt="" /> <div className="dis-flex-row dis-space-between"> <div></div> <div></div> <NavLink className="warning-btn1 mouse" to="/Home">回首頁 <i className='fas fa-home'></i></NavLink> <NavLink className="warning-btn2 mouse" to="/log_in">登入去 <i className='fas fa-sign-in-alt'></i></NavLink> <div></div> <div></div> </div> </div> </div> </div> </div> </div> } ``` [回上層 ExamContain.jsx](https://hackmd.io/8cLPGVhdRymXPrCLNYLuNw?view)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up