คำนำ: บล็อกเกอร์ได้แชร์การใช้งานพื้นฐานบางอย่างของ Knockoutjs และ bootstraptable ก่อน พวกเขาเป็นแอปพลิเคชั่นพื้นฐานทั้งหมดและไม่ได้ห่อหุ้มเลย พวกเขาเพียงแค่หลีกเลี่ยงค่าและการกำหนดตัวควบคุม HTML และยังห่างไกลจากการแสดงความประณีตของ MVVM เมื่อเร็ว ๆ นี้โครงการวางแผนที่จะใช้ KO อย่างเป็นทางการดังนั้นจึงได้ทำบรรจุภัณฑ์สำหรับ KO และ Bootstraptable และมีการแบ่งปันที่นี่เพื่ออ้างอิงโดย Park Friends สำหรับแนวคิดบรรจุภัณฑ์โปรดดูที่ Blog Park Master Xiao Qin หากเพื่อนในอุทยานมีวิธีที่ดีกว่าโปรดอย่าลังเลที่จะพูดคุย
บทความซีรีส์ที่น่าพิศวง:
Bootstarpable และ KnockoutJs รวมกันเพื่อให้ได้ฟังก์ชั่นของการเพิ่มการลบการแก้ไขและการตรวจสอบ [1]
bootstary และ knockoutjs รวมกันเพื่อให้ได้ฟังก์ชั่นของการเพิ่ม, การลบ, การแก้ไขและการตรวจสอบ [2]
1. ViewModel แรกจัดการการสืบค้น
การดำเนินการสาธิตยังคงดำเนินต่อไปฟังก์ชั่นการจัดการแผนกเป็นครั้งสุดท้าย การขยายตัวต่อไปนี้อธิบายโดยการไหลของข้อมูล
1. พื้นหลังส่งคืนการใช้งาน ViewModel ไปยังมุมมอง
Public ActionResult Index () {var model = new {tableParams = ใหม่ {url = "/แผนก/getDepartment", // pagesize = 2,}, urls = ใหม่ {delete = "/Department/Delete", edit = "/edit/edit" ดู (รุ่น);}รหัสสงสัย: โมเดลที่ส่งคืนที่นี่มีสามตัวเลือก
• TableParams: พารามิเตอร์การเริ่มต้นตารางหน้า เนื่องจากพารามิเตอร์เริ่มต้นถูกกำหนดไว้ใน JS พารามิเตอร์ที่ตั้งไว้ที่นี่เป็นพารามิเตอร์การเริ่มต้นเฉพาะหน้า
• URL: เส้นทาง URL ที่มีคำขอเพิ่มเติมการลบและการปรับเปลี่ยน
• QueryCondition: เงื่อนไขการสืบค้นของหน้า
2. รหัสหน้า cshtml
รหัสหน้า index.cshtml มีดังนี้:
@{layout = null;} <! doctype html> <html> <head> <meta name = "viewport" content = "width = device-width"/> <title> ดัชนี </title> <link href = "/content/bootstrap/css/css/bootstrap.css href = "~/content/bootstrap-table/bootstrap-table.min.css" rel = "stylesheet"/> <script src = "~/scripts/jQuery-1.9.1.min.js"> </script> src = "~/content/bootstrap-table/bootstrap-table.min.js"> </script> <script src = "~/content/bootstrap-table/locale/bootstrap-table-zh-cn.js"> </script> <script src = "~/scripts/scripts/script src = "~/scripts/knockout/knockout-3.4.0.min.js"> </script> <script src = "~/scripts/knockout/extensions/knockout.mapping-latest.js"> </script> <script src = "~/scripts/scripts src = "~/scripts/extensions/knockout.bootStraptable.js"> </script> <script type = "text/javascript"> $ (function () {var data = @html.raw document.getElementById ("div_index"));}); </script> </head> <body> <div id = "div_index" style = "padding: 0px; overflow-x: ซ่อน;"> <div> <div> data-bind = "value: queryCondition.name"> </div> <dable> คำอธิบายแผนก </label> <div> <อินพุตประเภท = "ข้อความ" data-bind = "value: queryCondition.des"> </div> <div style = "text-align: ขวา; type = "button" data-bind = "คลิก: queryclick"> query </button> </div> </dom> </div> </div> <div id = "แถบเครื่องมือ"> <button data-bind = "คลิก: addclick" type = "ปุ่ม" Aria-hidden = "true"> </span> แก้ไข </pution> <ปุ่ม data-bind = "คลิก: deleteClick" type = "ปุ่ม"> <span aria-hidden = "true"> </pan> ลบ </button> </div> <table data-bind = "bootstraptable ชื่อ </th> <th data-field = "ระดับ"> ระดับแผนก </th> <th data-field = "des"> คำอธิบาย </th> <th data-field = "stlCreateTime"> เวลาการสร้าง </th> </tr> </tead>รหัสข้อสงสัย: เช่นเดียวกับบทความก่อนหน้าคุณต้องอ้างถึง jQuery, bootstrap, bootstraptable, knockout และไฟล์อื่น ๆ ที่เกี่ยวข้อง นี่คือเอกสารสองฉบับต่อไปนี้:
• knockout.index.js: ห่อหุ้มคุณสมบัติและการผูกเหตุการณ์ที่เกี่ยวข้องกับหน้าการสืบค้น
• knockout.bootstraptable.js: ห่อหุ้มการเริ่มต้นของ bootstraptable และปรับแต่งวิธีการผูกมัดที่น่าพิศวง
การโต้ตอบหน้าเว็บข้างต้นทั้งหมดจะถูกห่อหุ้มใน JS สาธารณะดังนั้นจึงไม่จำเป็นต้องเขียนรหัสซ้ำจำนวนมากเช่นองค์ประกอบ DOM เพื่อรับการมอบหมายการเชื่อมโยงเหตุการณ์ ฯลฯ ในหน้า มีเพียงสองประโยคข้างต้นของ JS ที่เขียนในหน้านี้ มันไม่ง่ายมากเหรอ?
3. การห่อหุ้ม JS
มาดูไฟล์ JS สองไฟล์ที่กล่าวถึงข้างต้น, knockout.bootstable.js และ knockout.index.js
(1) Knockout.bootstraptable.js
(ฟังก์ชั่น ($) {// เพิ่มเมธอด bootstraptableViewModel ไปยัง ko.bootstraptableViewModel = function (ตัวเลือก) {var that = this; this.default = {toolbar: '#toolbar' พารามิเตอร์ (*) การแบ่งแยก: จริง, // ไม่แสดงหน้าจอแสดงผล (*) sidepagination: "เซิร์ฟเวอร์", // วิธีการ pagination: ไคลเอ็นต์ไคลเอนต์ไคลเอ็นต์, เซิร์ฟเวอร์การแบ่งหน้าเซิร์ฟเวอร์ (*) pagenumber: 1, // เริ่มต้นหน้าแรกเพื่อโหลด ได้รับการคัดเลือก (*) วิธี: 'Get', Search: จริง, // การค้นหาตารางจะปรากฏขึ้นหรือไม่? clicktoselect: จริง // การคลิกเพื่อเลือกแถวจะเปิดใช้งาน showtoggle: true,}; this.params = $. extend ({}, this.default, ตัวเลือก || {}); // รับบันทึกที่เลือกนี้ () {that.bootstraptable ("Refresh");};}; // เพิ่ม ko custom binding ko.bindinghandlers.bootstraptable = {init: ฟังก์ชั่น (องค์ประกอบ, valueaccessor, allbindingsaccessor, viewmodel) {// oparam $ (องค์ประกอบ). bootstraptable (oviewmodel.params); // เพิ่มวิธีการบูตตัวไปยัง ViewModel oviewModel.bootstraptable = function () {return $ ele.bootstraptable.apply ($ ele, อาร์กิวเมนต์); {}};}) (jQuery);รหัสสงสัย: รหัสข้างต้นส่วนใหญ่ทำสองสิ่ง
1. ViewModel ที่กำหนดเองเริ่มต้นโดย bootstraptable
2.
เพิ่มการผูกที่กำหนดเองของ KO
หากเพื่อนในอุทยานไม่เข้าใจการใช้งานที่มีผลผูกพันที่กำหนดเองคุณสามารถตรวจสอบโพสต์บล็อกสองบล็อกแรกของบล็อกเกอร์ (หนึ่ง) และ (สอง) สำหรับการแนะนำรายละเอียด
(2) Knockout.index.js
(ฟังก์ชั่น ($) {ko.bindingViewModel = function (data, bindelement) {var self = this; this.queryCondition = ko.mapping.fromjs (data.QueryCondition); this.defaultQueryParams = {queryParams: ฟังก์ชัน (พารามิเตอร์) param.offset; return params;}}; var tableParams = $ .extend ({}, this.defaultQueryParams, data.tableparams || {}); this.bootstraptable = ko.bootstraptableviewmodel (TableParams) ค่า) {// clear if (typeof (value) == "function") {this ('); id = "mymodal" tabindex = "-1" บทบาท = "กล่องโต้ตอบ" Aria-labelledby = "mymodallabel"> </div> '); dialog.load (data.urls.edit, null, function () {}); $ ("body") เมื่อปิดกล่องป๊อปอัพ (ชัดเจนนี้รวมถึงการล้างการเชื่อมและการล้างเหตุการณ์การลงทะเบียน) ko.cleannode (document.getElementById ("formedit")); dialog.remove (); self.bootstraptable.refresh ();});}; self.bootstraptable.getSelections (); ถ้า (arrrectedData.length <= 0 || arrrectedData.length> 1) {แจ้งเตือน ("แก้ไขเพียงหนึ่งบรรทัดในแต่ละครั้ง"); return;} var dialog = $ ('<div id = "mymodal" tabindex = "-1" aria-labelledby = "mymodallabel"> </div> '); dialog.load (data.urls.edit, arrrectedData [0], function () {}); $ ("body") ภาคผนวก การผูกและการล้างเหตุการณ์การลงทะเบียน) ko.cleanNode (document.getElementById ("formEdit")); dialog.remove (); self.bootstraptable.refresh ();});}; // ลบเหตุการณ์นี้ (! arrrectedData || arrrectedData.length <= 0) {แจ้งเตือน ("โปรดเลือกอย่างน้อยหนึ่งบรรทัด"); return;} $. ajax ({url: data.urls.delete, ประเภท: "โพสต์", contentType: {Alert (สถานะ); self.bootstraptable.refresh ();}});}; ko.applybindings (self, bindelement);};}) (jQuery);รหัสข้อสงสัย: JS นี้ส่วนใหญ่สรุปแอตทริบิวต์และการเชื่อมโยงเหตุการณ์ขององค์ประกอบหน้าและหลายสถานที่ที่ต้องอธิบาย
•สิ่งนี้ QUARYCONDITION = KO.Mapping.FromJS (data.QueryCondition): วัตถุประสงค์ของประโยคนี้คือการแปลงเงื่อนไขการสืบค้นที่ส่งผ่านจากพื้นหลังจากข้อมูล JSON ไปยังคุณลักษณะการตรวจสอบ เฉพาะการดำเนินการประโยคนี้เท่านั้นที่สามารถตรวจสอบแอตทริบิวต์และองค์ประกอบหน้าในทั้งสองทิศทาง
• self.bootstraptable.refresh (): ความหมายของประโยคนี้คือการรีเฟรชข้อมูลตาราง จริงๆแล้วมันเป็นวิธีการรีเฟรชของ bootstraptable ที่เรียกว่า แต่บล็อกเกอร์เพียงแค่ห่อหุ้มมันในไฟล์ knockout.bootstraptable.js
• dialog.load (data.urls.edit, null, function () {}): เมื่อเพิ่มและแก้ไขวิธีการโหลด () ของ jQuery ใช้ ฟังก์ชั่นของวิธีนี้คือการขอองค์ประกอบหน้าของ URL นี้และดำเนินการรหัส JS ของหน้าเว็บที่เกี่ยวข้องของ URL วิธีนี้มีประสิทธิภาพมากในการอ้างถึงไฟล์ JS แบบไดนามิกและเรียกใช้รหัสภายในไฟล์ JS
สุดท้ายแนบรหัสที่สอดคล้องกับเมธอด getDepartment () พื้นหลัง
[httpget] สาธารณะ jsonresult getDepartment (int limit, int onfset, ชื่อสตริง, สตริง des) {var lstres = แผนก model.getData (); ถ้า (! string.isnullorempty (ชื่อ)) {lstres = lstres.where (x => x.name.contains (name) (! string.isnullorempty (des)) {lstres = lstres.where (x => x.des.contains (des)). tolist ();} lstres.foreach (x => {x.strcreateTime = x.createTime.ToString ( lstres.skip (ออฟเซ็ต) .take (ขีด จำกัด ) .tolist (), ทั้งหมด = lstres.count}; return json (Ores, jsonrequestbehavior.allowget);}ณ จุดนี้ฟังก์ชั่นการสืบค้นและการล้างของหน้าการสืบค้นสามารถรับรู้ได้
คุณยังมีคำถามอยู่: ถ้าเราต้องการปรับแต่งเหตุการณ์ของ bootstraptable? ไม่สามารถส่งผ่าน ViewModel ในพื้นหลังใช่ไหม?
อันที่จริงวิธีการจัดกิจกรรม JS ไม่สามารถส่งผ่านจากพื้นหลังได้ดังนั้นเราจำเป็นต้องปรับแต่งวิธีการประมวลผลของเหตุการณ์ในส่วนหน้าตัวอย่างเช่นเราสามารถทำได้:
<script type = "text/javascript"> $ (function () {var data = @html.raw (newtonsoft.json.jsonconvert.serializeObject (รุ่น)); data.tableparams.onloadsuccess = function (data) document.getElementById ("div_index"));}); </script>2. รับการแก้ไข ViewModel ที่สอง
หนึ่งใน ViewModels ด้านบนจัดการฟังก์ชั่นการสืบค้นและการลบ แต่การเพิ่มและแก้ไขยังต้องการการสนับสนุนของ ViewModel อื่น มาดูการใช้งานแพ็คเกจการแก้ไข
1. การใช้งาน ActionResult
ผ่านการค้นหารหัสด้านบนเราสามารถรู้ได้ว่าเมื่อผู้ใช้คลิกที่เพิ่มและแก้ไขมุมมองอื่นจะได้รับการร้องขอ→/แผนก/แก้ไข ลองมาดูการใช้งาน Edit View
Public ActionResult Edit (รุ่นแผนก) {var OresModel = ใหม่ {editModel = รุ่น, urls = new {submit = model.id == 0? "/แผนก/เพิ่ม": "/แผนก/อัปเดต"}}; Return View (OresModel);}รหัสสงสัย: รหัสข้างต้นนั้นง่ายมากซึ่งก็คือการส่งคืน ViewModel ไปยังหน้ามุมมองที่มีเอนทิตีที่แก้ไขและ URL ที่ส่งมา ไม่ว่าจะเป็นคีย์หลักของเอนทิตีนี้จะถูกกำหนดโดยการกระทำในปัจจุบันเป็นนิติบุคคลใหม่หรือเอนทิตีแก้ไข
2. รหัส cshtml
แก้ไขรหัส CSHTML มีดังนี้:
<form id = "formedit"> <div role = "document"> <div> <div> <button type = "ปุ่ม" data-dismiss = "modal" aria-label = "close"> <span aria-hidden = "true"> × </span> ชื่อ </label> <input type = "text" name = "txt_departmentName" data-bind = "value: editModel.name" placeholder = "ชื่อแผนก"> </div> <div> <label for = "txt_departmentLevel" placeHolder = "ระดับแผนก"> </div> <div> <label for = "txt_des"> คำอธิบาย </label> <อินพุต type = "text" name = "txt_des" data-bind = "value: editModel.des" placeHolder = "descriptive"> </div> Aria-hidden = "true"> </span> ปิด </button> <button type = "ส่ง"> <span aria-hidden = "true"> </span> บันทึก </button> </div> </div> </form> <link href = "~/bootstrapvalidator src = "~/content/bootstrapvalidator/js/bootstrapvalidator.js"> </script> <script src = "~/scripts/extensions/knockout.edit.js"> </script> <script type = "text/javascript"> $ ( @html.raw (newtonsoft.json.jsonconvert.serializeObject (รุ่น)); ko.bindingeditviewmodel (editData, {});รหัสสงสัย: เนื่องจากเราได้เพิ่มองค์ประกอบการตรวจสอบ BootstrapValidator เราจึงต้องอ้างอิง JS และ CSS ที่เกี่ยวข้อง ไฟล์นี้ knockout.edit.js ส่วนใหญ่สรุปคุณสมบัติและการเชื่อมโยงเหตุการณ์ของหน้าแก้ไข มาดูรหัสการใช้งานของ JS นี้กันเถอะ
3. การห่อหุ้ม JS
knockout.edit.js รหัส:
(ฟังก์ชั่น ($) {ko.bindingEdItViewModel = ฟังก์ชั่น (data, chalidatorfields) {var that = {}; that.editModel = ko.mapping.fromjs (data.editModel); ฟังก์ชั่น (varidator) arrrectedData = ko.tojs (that.editModel); $. ajax ({url: data.urls.submit, ประเภท: "post", contentType: 'application/json', ข้อมูล: json.stringify {Alert (สถานะ);}}); $ ("#mymodal"). modal ("ซ่อน");}}; document.getElementById ("formEdit"));};}) (jQuery);รหัสข้อสงสัย: JS นี้ส่วนใหญ่ห่อหุ้มคุณสมบัติของโมเดลแก้ไขและการเชื่อมโยงเหตุการณ์ที่ส่ง เนื่องจากใช้องค์ประกอบการตรวจสอบ Bootstrapvalidator จึงจำเป็นต้องมีการส่งแบบฟอร์ม ในความเป็นจริง ID หน้าไม่ควรปรากฏใน JS สาธารณะเช่น "FormEdit" และ "Mymodal" ด้านบน สิ่งนี้สามารถส่งผ่านเป็นพารามิเตอร์ซึ่งจำเป็นต้องได้รับการปรับให้เหมาะสม พารามิเตอร์ ValidatorFields แสดงถึงฟิลด์การตรวจสอบขององค์ประกอบการตรวจสอบ หากแบบฟอร์มไม่จำเป็นต้องมีการตรวจสอบก็โอเคที่จะผ่าน JSON ที่ว่างเปล่าหรือไม่ เราไม่ได้ทำการตรวจสอบภาคสนามในบทความข้างต้น ในความเป็นจริงการพูดโดยทั่วไปตารางพื้นฐานจะมีหนึ่งหรือหลายฟิลด์ที่ไม่ว่างเปล่าเช่นการตรวจสอบชื่อแผนกที่ไม่ว่างเปล่า รหัสในหน้า edit.cshtml ถูกเปลี่ยนเป็นสิ่งนี้:
<form id = "formedit"> <div role = "document"> <div> <div> <button type = "ปุ่ม" data-dismiss = "modal" aria-label = "close"> <span aria-hidden = "true"> × </span> ชื่อ </label> <input type = "text" name = "name" data-bind = "value: editModel.name" placeholder = "ชื่อแผนก"> </div> <div> <label for = "txt_departmentlevel"> แผนก </label> placeHolder = "DepartmentLevel"> </div> <div> <label for = "txt_des"> คำอธิบาย </label> <อินพุต type = "text" name = "des" data-bind = "value: editModel.des" placeholder = "des"> </div> type = "ส่ง"> <span aria-hidden = "true"> </span> บันทึก </button> </div> </div> </form> <link href = "~/content/bootstrapvalidator/css/bootstrapvalidator.css" rel = "stylesheet"/> < src = "~/content/bootstrapvalidator/js/bootstrapvalidator.js"> </script> <script src = "~/scripts/extensions/knockout.edit.js"> </script> <script type = "text/javascript"> $ ( @html.raw (newtonsoft.json.jsonconvert.serializeObject (รุ่น)); ko.bindingeditviewmodel (editdata, {ชื่อ: {ตัวตรวจสอบ: {notempty: {ข้อความ: 'ชื่อไม่สามารถว่างเปล่า!จากนั้นจะได้รับการตรวจสอบโดยอัตโนมัติเมื่อส่ง:
หมายเหตุ: ชื่อแอตทริบิวต์การตรวจสอบสอดคล้องกับแอตทริบิวต์ชื่อของแท็กอินพุตดังนั้นในการตรวจสอบแอตทริบิวต์ชื่อนี้จะต้องตั้งค่าอย่างถูกต้อง
เป็นการดีที่สุดที่จะแนบวิธีพื้นหลังสำหรับการเพิ่มการลบและการแก้ไข:
[httppost] สาธารณะ jsonresult add (แผนก odata) {Departmentmodel.add (odata); return json (ใหม่ {}, jsonrequestbehavior.allowget);} [httppost] jsonresult สาธารณะ jsonRequestBehavior.allowget);} [httppost] สาธารณะ jsonresult delete (รายการ <erection> odata) {DepartmentModel.delete (Odata); return json (ใหม่ {}, jsonrequestbehavior.allowget);}ณ จุดนี้ผลของการเพิ่มการลบการแก้ไขและการตรวจสอบของหน้าทั้งหมดก็โอเค มาดูเอฟเฟกต์สั้น ๆ :
3. สรุป
ข้างต้นเพียงแค่สรุปการเพิ่มการลบการดัดแปลงและบริการค้นหาของ bootstarpable+ko ซึ่งเป็นเพียงแพ็คเกจหลัก หากคุณต้องการใช้สิ่งเหล่านี้กับโครงการของคุณคุณอาจต้องใช้มาตรการเพิ่มประสิทธิภาพอย่างง่าย ๆ เช่น:
1. หากเป็นเพียง ViewModel ของหน้าจะดีกว่าที่จะเขียนลงในหน้ามุมมองโดยตรงโดยไม่ต้องส่งคืนจาก ActionResult ในพื้นหลังและจะช่วยประหยัดปัญหาของการทำให้เป็นอนุกรมและพารามิเตอร์ที่ผ่าน สิ่งนี้จะต้องได้รับการปรับให้เหมาะสม
2. ID ขององค์ประกอบหน้าไม่ควรปรากฏในสาธารณะ JS องค์ประกอบหน้าสามารถส่งผ่านพารามิเตอร์
3. เพิ่มและแก้ไขวิธีการจัดกิจกรรมเพื่อให้มีรหัสซ้ำจำนวนมากในกล่องป๊อปอัพ วิธีที่ดีที่สุดในการทำส่วนนี้คือการห่อหุ้มกล่องป๊อปอัพลงในองค์ประกอบแยกต่างหากเพื่อเรียกมันซึ่งสามารถลดรหัส JS ส่วนใหญ่ได้
4. หากมีองค์ประกอบกล่องแบบเลื่อนลงในเงื่อนไขการสืบค้นและคุณสมบัติที่แก้ไขแล้วคุณอาจต้องห่อหุ้มแหล่งข้อมูลและแอตทริบิวต์อื่น ๆ ของกล่องแบบเลื่อนลง ส่วนนี้เป็นเรื่องธรรมดามาก หลังจากบล็อกเกอร์ได้แยกการสาธิตแล้วเพิ่มชิ้นนี้
ด้านบนเป็นวิธีการแก้ปัญหาสำหรับ bootstarpable + knockoutjs ที่แนะนำโดยตัวแก้ไขเพื่อให้ได้การเพิ่มการลบการปรับเปลี่ยนและการค้นหา (3) ViewModels ทั้งสองได้เสร็จสิ้นการเพิ่มการลบการดัดแปลงและการค้นหา ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน หากคุณมีคำถามใด ๆ โปรดฝากข้อความถึงฉันและบรรณาธิการจะตอบกลับทุกคนในเวลา ขอบคุณมากสำหรับการสนับสนุนเว็บไซต์ Wulin.com!