ในบทความก่อนหน้านี้ฉันได้แนะนำให้คุณรู้จักกับการรวมกันของ bootstable และ knockoutjs เพื่อใช้การเพิ่มการลบการปรับเปลี่ยนและฟังก์ชั่นการค้นหา [1] และแนะนำการใช้งานพื้นฐานของการน็อคเอาท์ ต่อไปเราจะแนะนำให้คุณรู้จักกับคุณผ่านบทความนี้ต่อไป หากคุณวางแผนที่จะใช้ KO ในการทำโครงการลองมาดูกันเถอะ!
Bootstrap เป็นเฟรมเวิร์กส่วนหน้าเป็นสิ่งที่ดีสำหรับการปลดปล่อยนักพัฒนาเว็บ มันแสดงให้เห็นว่า UI นั้นสูงมากบรรยากาศและระดับไฮเอนด์ ในทางทฤษฎีคุณไม่จำเป็นต้องเขียนบรรทัด CSS เพียงเพิ่มแอตทริบิวต์ที่เหมาะสมลงในแท็ก
KnockoutJS เป็นกรอบ MVVM ที่ใช้งาน JavaScript ดีมาก. ตัวอย่างเช่นหลังจากเพิ่มหรือลดรายการข้อมูลรายการไม่จำเป็นต้องรีเฟรชส่วนควบคุมทั้งหมดหรือเขียน JS Addition และการลบโหนดด้วยตัวเอง เพียงกำหนดเทมเพลตและแอตทริบิวต์ที่ตรงตามคำจำกัดความของไวยากรณ์ พูดง่ายๆคือเราต้องให้ความสนใจกับการเข้าถึงข้อมูลเท่านั้น
1. ดูตัวอย่างของเอฟเฟกต์
ในความเป็นจริงมันไม่มีผล มันเป็นเพียงการเพิ่มการลบการดัดแปลงและการค้นหาอย่างง่าย กุญแจยังคงอยู่ในรหัส การใช้ KO สามารถบันทึกการดำเนินการเชื่อมโยงข้อมูล DOM จำนวนมาก ด้านล่างคือรหัส JS สำหรับตรรกะทั้งหมดของการเพิ่มการลบการแก้ไขและการค้นหา:
เอฟเฟกต์หน้า:
2. ตัวอย่างรหัส
โอเคมาถึงจุด! บล็อกเกอร์วางแผนที่จะแนะนำในสองส่วน ส่วนแรกคือส่วนการเริ่มต้นตารางและส่วนที่สองคือการเพิ่มการทำงานของปุ่มการลบและการปรับเปลี่ยนส่วน
1. การเริ่มต้นตาราง
1.1. การตระเตรียม
ก่อนอื่นให้ดูที่ไฟล์ JS และ CSS ที่ต้องอ้างอิง
<link href = "~/content/bootstrap/css/bootstrap.min.css" rel = "stylesheet"/> <link href = "~/content/bootstrap-table/bootstrap-table.min.css" rel = "StylesHeet"/> src = "~/content/bootstrap/js/bootstrap.min.js"> </script> <script src = "~/content/bootstrap-table/bootstrap-table.min.js"> </script> src = "~/scripts/knockout/knockout-3.4.0.min.js"> </script> <script src = "~/scripts/knockout/extensions/knockout.mapping-latest.js"> </script> src = "~/scripts/ection.js"> </script>
พวกเขาทั้งหมดใช้ไฟล์ CSS และ JS ที่ใช้กันทั่วไป เรามีไฟล์ JS ที่กำหนดเองสองไฟล์: Knockout.bootstraptable.js และ Department.js ในบทความก่อนหน้านี้เราแนะนำว่าการใช้ KO สามารถปรับแต่งการผูกมัดข้อมูลของเรา ในทำนองเดียวกันสำหรับการเชื่อมโยงของตารางเรายังกำหนดการเชื่อมโยงที่กำหนดเองรหัสภายใน knockout.bootstraptable.js
// เพิ่ม KO ที่มีผลผูกพันกับ KO.BindingHandlers.MyBootStraptable = {init: ฟังก์ชั่น (องค์ประกอบ, valueAccessor, allbindingsAccessor, viewModel) {// oparam ที่นี่คือมุมมองที่ถูกผูกไว้ Bootstraptable Method to ViewModel OviewModel.BootStraptable = function () {return $ ele.bootstraptable.apply ($ ele, อาร์กิวเมนต์);}}, อัปเดต: ฟังก์ชั่น (องค์ประกอบ, valueaccessor, allbindingsaccessor, viewmodel) {}}; ko.bootstraptableViewModel = function (ตัวเลือก) {var that = this; this.default = {search: true, // ว่าจะแสดงการค้นหาตารางหรือไม่? MinimumCountColumns: 2, // จำนวนคอลัมน์ขั้นต่ำที่อนุญาตให้คลิกที่: จริง, // ที่จะเปิดใช้งานคลิกเลือกแถว showtoggle: true,}; arrres;}; // รีเฟรช this.refresh = function () {that.bootstraptable ("Refresh");};};}) (jQuery);รหัสสงสัย: ไฟล์ JS นี้ส่วนใหญ่ทำสองสิ่ง
1. ปรับแต่งคุณสมบัติที่ผูกมัดข้อมูล mybootstary สำหรับวิธีการอัปเดตใน ko.bindinghandlers.mybootstraptable ไม่จำเป็นต้องกำหนด
2. ห่อหุ้ม bootstraptable โดยการเพิ่ม bootstraptableViewModel ลงในวัตถุ KO
1.2. เริ่มการเชื่อมโยงของแท็ก HTML
<table id = "tb_dept" data-bind = "mybootstarpable: $ root"> <tr> <th data-checkbox = "true"> </th> <th data-field = "ชื่อ"> ชื่อแผนก </th> <th data-field = "ระดับ" เวลา </th> </tr> </teaad> </table>
รหัสสงสัย: กำหนดแท็กตารางและใช้การเชื่อมโยงที่กำหนดเองกับ mybootstraptable ดังที่ได้กล่าวไว้ในบทความก่อนหน้านี้ $ root สามารถเข้าใจได้ว่าเป็นความหมายของการเริ่มต้น เพื่อความเรียบง่ายคอลัมน์ทั้งหมดจะถูกเขียนโดยตรงใน <th>
1.3. เปิดใช้งานการเชื่อมโยงของ KO
หลังจากโหลดหน้าเว็บแล้วเริ่มการเชื่อมโยงของ KO:
// เริ่มต้น $ (function () {// 1, Init Table TableInit.init (); // 2, ลงทะเบียน add-on, การลบและการปรับเปลี่ยนเหตุการณ์การทำงาน. operateInit ();}); // เริ่มต้นตาราง tableInit = {init: function () '/แผนก/getDepartment', // request url (*) วิธี: 'get', // วิธีการร้องขอ (*) แถบเครื่องมือ: '#toolbar', // คอนเทนเนอร์ใดที่ใช้สำหรับปุ่มเครื่องมือ QueryParams: ฟังก์ชั่น (param) {return {limit: param.limit, Offset: param.offset}; SidePagination: "เซิร์ฟเวอร์", // วิธีการปนเปื้อน: ไคลเอนต์ไคลเอนต์การแบ่งหน้าไคลเอ็นต์, เซิร์ฟเวอร์เซิร์ฟเวอร์การแบ่งหน้า (*) pagenumber: 1, // เริ่มต้นหน้าแรกที่จะโหลด, หน้าแรกเริ่มต้นหน้า: 10, // จำนวนบรรทัดบันทึกต่อหน้า (*) pagelist: [10, 25, 50, 100] document.getElementById ("tb_dept"));}};รหัสข้อสงสัย: หลังจากโหลดหน้าเว็บแล้วให้เรียกวัตถุ BootstraptableViewModel ที่ห่อหุ้มไว้ด้านบนเพื่อรวมพารามิเตอร์ที่ส่งผ่านและในที่สุดก็เปิดใช้งานการเชื่อมโยงและเปิดใช้งานสิ่งนี้ MyViewModel เป็น ViewModel ที่ถูกผูกไว้ รหัสการดีบักแสดงให้เห็นว่าเมื่อ ko.applybindings (this.myviewmodel, document.getElementById ("tb_dept")); ดำเนินการ; การเชื่อมโยงที่กำหนดเองจะมีผลและโปรแกรมจะป้อนวิธีการเริ่มต้นของวัตถุ KO.BindingHandlers.MyBootstartable เพื่อเริ่มต้น bootstartable นี่คือจุดที่จะอธิบาย:
init: ฟังก์ชั่น (องค์ประกอบ, valueAccessor, allbindingsAccessor, viewModel) {// oparam นี่คือ bound viewModelVar oviewModel = valueAccessor (); var $ ele = $ (องค์ประกอบ) $ ele.bootstraptable.apply ($ ele, อาร์กิวเมนต์);}}ในวิธีการเริ่มต้นด้านบนผ่านพารามิเตอร์ที่สอง ValueAccessor เราได้รับมุมมองที่ถูกผูกไว้ในปัจจุบันซึ่งเป็นวัตถุของสิ่งนี้ MyViewModel ด้านบน บล็อกเกอร์คิดว่าสิ่งนี้เอื้อต่อความเข้าใจของคุณเกี่ยวกับตรรกะของการเชื่อมโยงที่กำหนดเอง โดยทั่วไปเมื่อเราเรียกใช้ประโยคนี้ var $ ele = $ (องค์ประกอบ). bootstraptable (oviewmodel.params);, การเริ่มต้นตารางของเราเสร็จสิ้นแล้ว บล็อกเกอร์กำหนดคอลเลกชันสำหรับวิธีการที่สอดคล้องกันในพื้นหลัง เพื่อความสมบูรณ์ฉันจะโพสต์ไว้ที่นี่:
ผู้เข้าร่วมประชุม
2. การทำงานของปุ่ม
ข้างต้นคือการใช้การผูกมัดข้อมูลที่กำหนดเองของเราผ่านการเริ่มต้นของ bootstraptable มาสัมผัสประสบการณ์“ Shuangweiwai” โดยใช้แอตทริบิวต์การตรวจสอบโดยใช้การทำงานของปุ่มด้านล่าง
2.1. ดูเพจ
ขั้นแรกให้กำหนดปุ่มเพิ่มการลบของเราในหน้ามุมมอง
<div id = "แถบเครื่องมือ"> <button id = "btn_add" type = "ปุ่ม"> <span aria-hidden = "true"> </span> เพิ่ม </button> <button id = "btn_edit" type = "ปุ่ม"> aria-hidden = "true"> </span> ลบ </pution> </div>
เพื่อความเรียบง่ายบล็อกเกอร์ใช้กล่องป๊อปอัพที่ซ่อนอยู่เพื่อบรรจุกล่องข้อความที่เพิ่มและแก้ไขใหม่ แน่นอนว่าโดยทั่วไปคุณอาจใช้มุมมองบางส่วนที่นี่และอาจมีการแก้ไข cshtml ในโครงการของคุณ แต่ที่นี่บล็อกเกอร์วางสิ่งเหล่านี้ในหน้าเดียวเพราะนี่ไม่ใช่จุดสนใจของข้อความ
<div id = "mymodal" tabindex = "-1" role = "กล่องโต้ตอบ" Aria-labelledby = "mymodallabel"> <div role = "document"> <div> <div> <button type = "ปุ่ม" data-dismiss = "modal" aria-label = "close"> id = "mymodallabel"> การดำเนินการ </h4> </div> <div> <label for = "txt_departmentname"> ชื่อแผนก </label> <อินพุต type = "text" name = "txt_departmentname" data-bind = "value: name" id = "txt_departmentname สำหรับ = "txt_departmentlevel"> ระดับแผนก </label> <อินพุต type = "text" name = "txt_departmentlevel" data-bind = "value: ระดับ" id = "txt_departmentlevel" placeLevel = "typectionLevel"> </div> data-bind = "value: des" id = "txt_des" placeholder = "คำอธิบาย"> </div> </div> <div> <button type = "ปุ่ม" data-dismiss = "modal"> <span aria-hidden = "true"> </span> ปิด </button> aria-hidden = "true"> </span> บันทึก </putton> </div> </div> </div>
2.2. การทำงานของปุ่มเริ่มต้น JS
// การดำเนินการ var การดำเนินการ = {// เริ่มต้นปุ่มเหตุการณ์ดำเนินการ: function () {this.operateAddd (); this.operateUpdate (); this.operateDelete (); this.departmentModel = {id: ko.obsarvable (), ชื่อ: ko.observable () ko.observable ()};}, // เพิ่มการดำเนินการ: function () {$ ('#btn_add'). on ("คลิก", function () {$ ("#mymodal"). modal (). on ("shown.bs.modal", function () ko.observable (), ระดับ: ko.observable (), des: ko.observable (), createTime: ko.observable ()}; ko.utils.extend (ทำงาน. departmentmodel, oemptymodel); document.getElementById ("mymodal")); eraperate.operatesave ();}). on ('hidden.bs.modal', ฟังก์ชั่น () {ko.cleannode (document.getElementById ("mymodal");});});}); {$ ('#btn_edit'). on ("คลิก", function () {$ ("#mymodal"). modal (). on ("shown.bs.modal", function () {var arrrectedData = tableinit.myViewModel.getSelections () แถวข้อมูลที่เลือกไปยัง ViewModelko.Utils.extend (ancal.departmentmodel, ko.mapping.fromjs (arrrrectedData [0])); ko.applybindings document.getElementById ("mymodal")); erperate.operatesave ();}). on ('hidden.bs.modal', ฟังก์ชั่น () {// ล้างการผูกเมื่อปิดกล่องป๊อปอัพ เหตุการณ์) ko.cleanNode (document.getElementById ("mymodal"));});});});});});}, // ลบ: ฟังก์ชัน () {$ ('#btn_delete') TableInit.myViewModel.getSelections (); $. ajax ({url: "/แผนก/ลบ", ประเภท: "โพสต์", contentType: 'แอปพลิเคชัน/JSON', ข้อมูล: json.stringify (arrrectedData), ความสำเร็จ: ฟังก์ชัน (ข้อมูลสถานะ) {Alert (สถานะ); // TableInit.myViewModel.Refresh ();}});});});}, // บันทึกการทำงานของข้อมูล: ฟังก์ชั่น () {$ ('#btn_submit') ViewModel to data modelvar odatamodel = ko.tojs (OviewModel); var funcname = odatamodel.id?"update"::":";; {Alert (สถานะ); TableInit.myViewModel.Refresh ();}});});});}, // การตรวจสอบข้อมูลการตรวจสอบข้อมูล: ฟังก์ชั่น (arr) {ถ้า (arr.length <= 0) {Alert ("โปรดเลือกอย่างน้อยหนึ่งแถว") false;} return true;}}รหัสความสงสัย: บอกเราเกี่ยวกับตรรกะการดำเนินการที่นี่ อันดับแรกให้โทรหาผู้ดำเนินการ. operateInit (); ในวิธี $ (function () {}) ในเมธอด operatorInit () ลงทะเบียนเหตุการณ์คลิกของปุ่มบนหน้าและกำหนดสิ่งนี้ departmentModel เป็น ViewModel ที่แก้ไขใหม่ ViewModel นี้กำหนดคุณลักษณะการตรวจสอบที่สอดคล้องกับองค์ประกอบหน้า คุณยังจำข้อมูลบางอย่างในกล่องป๊อปอัพที่ซ่อนอยู่ด้านบนได้หรือไม่? ใช่ค่าที่สอดคล้องกันในนั้นสอดคล้องกับแอตทริบิวต์การตรวจสอบที่นี่ หลังจากตั้งค่าการเชื่อมโยงการเปลี่ยนแปลงการตรวจสอบทั้งหมดใน JS ที่นำไปสู่สิ่งนี้ departmentModel จะเรียกค่าของแท็กที่มีผลผูกพันในอินเทอร์เฟซเพื่อเปลี่ยน ในทางตรงกันข้ามการเปลี่ยนแปลงค่าของค่าของแท็กทั้งหมดในอินเทอร์เฟซจะทำให้การเปลี่ยนแปลงของค่าแอตทริบิวต์การตรวจสอบอย่างหลีกเลี่ยงไม่ได้ นี่คือการผูกสองทางที่เรียกว่า ลองมาดูการดำเนินการของรายละเอียดสองทาง
2.3. การดำเนินการใหม่
$ ('#btn_add') บน ("คลิก", function () {$ ("#mymodal"). modal (). on ("shown.bs.modal", function () {var oemptymodel = {id: ko.obsarvable (), ชื่อ: ko.observable () ko.observable ()}; ko.utils.extend (ange.departmentmodel, oemptymodel); ko.applybindings (unportaTe.departmentModel, document.getElementById ("mymodal"); {ko.cleanNode (document.getElementById ("mymodal")));});});เมื่ออินเทอร์เฟซของเราทริกเกอร์การดำเนินการใหม่กล่องโมดอลที่ซ่อนอยู่ดังกล่าวข้างต้นจะปรากฏขึ้นก่อน เมื่อกล่องโมดอลปรากฏขึ้นก่อนอื่นให้กำหนด ViewModel ที่ว่างเปล่าจากนั้นโทรหา ko.utils.extend (ancerate.departmentmodel, oemptymodel); ประโยคนี้จะเขียนทับ Global Operating.departmentModel โดย ViewModel ที่ว่างเปล่า ฟังก์ชั่นของวิธี ko.utils.extend () คล้ายกับฟังก์ชั่นของ $. extend () ใน jQuery ทั้งวัตถุก่อนหน้านี้จะถูกรวมเข้ากับวัตถุที่ตามมาและหลังจากการผสานการเชื่อมโยงจะเปิดใช้งานโดยใช้ ViewModel ใหม่ หลังจากเปิดใช้งานการเชื่อมโยงให้ลงทะเบียนเหตุการณ์คลิกของปุ่มบันทึก เมื่อเพิ่มสิ่งนี้กล่องโมดอลจะปรากฏขึ้น เนื่องจากแอตทริบิวต์การตรวจสอบใน ViewModel นั้นว่างเปล่าทั้งหมดค่าขององค์ประกอบอินเตอร์เฟสที่เกี่ยวข้องจะถูกล้างด้วยดังนั้นเราจึงเห็นสิ่งนี้ในการเพิ่มใหม่:
เมื่อกล่องป๊อปอัพถูกปิดเราจะดำเนินการ ko.cleannode (document.getElementById ("mymodal")); ผ่านเหตุการณ์ที่ปิด ประโยคนี้มีความสำคัญมากเพราะสำหรับ DOM เดียวกัน KO สามารถผูกมัดได้เพียงครั้งเดียว หากคุณต้องการผูกมัดอีกครั้งคุณต้องล้างการผูกก่อน นอกจากนี้วิธีการ CleanNode () จะไม่เพียง แต่จะล้างการเชื่อมโยง แต่ยังล้างเหตุการณ์ที่ลงทะเบียนใน DOM คุณต้องให้ความสนใจเมื่อใช้งาน!
2.4. การแก้ไขการดำเนินงาน
$ ('#btn_edit') บน ("คลิก", ฟังก์ชัน () {$ ("#mymodal"). modal (). on ("shown.bs.modal", function () {var arrrectedData = tableInit.myViewModel.getSelections () ของข้อมูลที่มีรูปแบบข้อมูลไปยัง ViewModelko.utils.extend (ancal.departmentmodel, ko.mapping.fromjs (arrrecteddata [0])); ko.applybindings (uncerate.departmentmodel. function () {// ล้างการเชื่อมโยงเมื่อปิดกล่องป๊อปอัพ (ชัดเจนรวมถึงการล้างการเชื่อมและการล้างเหตุการณ์การลงทะเบียน) ko.cleanNode (document.getElementById ("mymodal"));});});});เมื่อเราทริกเกอร์การดำเนินการแก้ไขอินเทอร์เฟซยังคงปรากฏขึ้น ในเหตุการณ์ป๊อปอัพของกล่องป๊อปอัพเราจะใช้แถวที่เลือกในปัจจุบันแล้วตรวจสอบว่าเลือกแถวหรือไม่ เป็นการดีที่สุดที่จะแปลงวัตถุ JSON ทั่วไปเป็น ViewModel ด้วยแอตทริบิวต์การตรวจสอบผ่านประโยค ko.mapping.fromjs (arrrectedData [0]) ดังที่ได้กล่าวไว้ในบทความก่อนหน้านี้วิธีนี้ต้องการการสนับสนุนของไฟล์ JS ที่น่าพิศวง หลังจากการแปลง ViewModel ยังคงได้รับการปรับปรุงผ่านวิธี KO.utils.extend () จากนั้นเปิดใช้งานการเชื่อมโยง เนื่องจาก ViewModel ได้รับการอัปเดตโดยข้อมูลของแถวที่เลือกในปัจจุบันผลลัพธ์คือ:
2.5. บันทึกการดำเนินงาน
หลังจากเพิ่มและแก้ไขกล่องป๊อปอัพให้คลิกบันทึกหลังจากแก้ไขข้อมูลที่เกี่ยวข้องและเหตุการณ์บันทึกจะถูกเรียกใช้
$ ('#btn_submit') บน ("คลิก", ฟังก์ชัน () {// ดึงมุมมองปัจจุบันของ ViewModelVar OviewModel = Operating.departmentModel; // แปลง viewModel เป็น data modelvar odatamodel = ko.tojs (OviewModel); varmodel odatamodel.id?"update":"Add";$.ajax( {url: "/แผนก/"+funcname, ประเภท: "โพสต์", ข้อมูล: odatamodel, ความสำเร็จ: ฟังก์ชั่น (ข้อมูล, สถานะ) {แจ้งเตือน (สถานะ); tableinit.myviewmodel.refreshเมื่อมีการเรียกเหตุการณ์การบันทึกก่อนอื่นเราจะได้รับ ViewModel ที่ถูกผูกไว้กับหน้านั่นคือการดำเนินการส่วนแบ่งส่วนโมเดลจากนั้นใช้วิธี KO.TOJS () เพื่อแปลง ViewModel ด้วยแอตทริบิวต์การตรวจสอบเป็นวัตถุ JSON ที่มีข้อมูลบริสุทธิ์ วิธีการนี้อยู่ใน KO และไม่ต้องการการสนับสนุน JS อื่น ๆ หลังจากได้รับวัตถุ JSON ให้ส่งคำขอ AJAX เพื่อเพิ่มหรือแก้ไขข้อมูล สิ่งนี้สะท้อนให้เห็นถึงการผูกสองทางดี หลังจากค่าของกล่องข้อความทั้งหมดในการเปลี่ยนแปลงอินเทอร์เฟซการเปลี่ยนแปลงของการดำเนินการ departmentmodel จะถูกเรียกใช้เช่นกัน
2.6. ลบการทำงาน
ไม่มีอะไรจะพูดเกี่ยวกับการลบและไม่มีส่วนเกี่ยวข้องกับ KO
3. สรุป
ข้างต้นแนะนำการใช้งานร่วมกันของ KO และ bootstraptable ผ่านการเพิ่มการลบการดัดแปลงและการดำเนินการค้นหาอย่างง่าย KO สามารถปลดปล่อยคุณจาก DOM และมุ่งเน้นไปที่ ViewModel เมื่อดูที่รหัส JS ทั้งหมดคุณแทบจะไม่เห็น jQuery's val (), text () และการดำเนินการอื่น ๆ เพื่อรับและกำหนดค่าให้กับอินเตอร์เฟส DOM มันดูสะอาดและสดชื่นและระดับสูงหรือไม่? แน่นอนว่านี่อาจเป็นเพียงการใช้งานขั้นพื้นฐานของ KO ท้ายที่สุดแล้วบล็อกเกอร์ได้เรียนรู้ KO เป็นเวลา 3 วันเท่านั้นและต้องมีการสำรวจประเพณีขั้นสูงมากขึ้น เมื่อคุณคุ้นเคยกับมันในขณะที่คุณจะแบ่งปันประเพณีขั้นสูงกับทุกคน หากคุณคิดว่าบทความนี้สามารถช่วยให้คุณเข้าใจหลักการของ KO และการใช้งานของมันคุณอาจแนะนำเช่นกัน บรรณาธิการรู้สึกขอบคุณที่นี่!
ข้างต้นเป็นเนื้อหาทั้งหมดของการรวมกันของ bootstary และ knockoutjs เพื่อใช้การเพิ่มการลบการปรับเปลี่ยนและฟังก์ชั่นการค้นหา [2] ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน!