JS元件系列——BootstrapTable+KnockoutJS實現增刪改查解決方案(二)
前言:上篇 JS元件系列——BootstrapTable+KnockoutJS實現增刪改查解決方案(一) 介紹了下knockout.js的一些基礎用法,由於篇幅的關係,所以只能分成兩篇,望見諒!昨天就覺得應該快點完成下篇,要不然有點標題黨的感覺,思及此,博主心有不安,於是加班趕出了下篇。如果你也打算用ko去做專案,且看看吧!
一、效果預覽
其實也沒啥效果,就是簡單的增刪改查,重點還是在程式碼上面,使用ko能夠大量節省介面DOM資料繫結的操作。下面是整個整個增刪改查邏輯的js程式碼:
頁面效果:
二、程式碼示例
好了,進入重點吧!博主打算分兩塊介紹,第一部分是表格初始化部分,第二部分是按鈕操作增刪改部分。
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" /> <script src="~/scripts/jquery-1.9.1.min.js"></script> <script src="~/Content/bootstrap/js/bootstrap.min.js"></script> <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/knockout/knockout-3.4.0.min.js"></script> <script src="~/scripts/knockout/extensions/knockout.mapping-latest.js"></script> <script src="~/Content/bootstrap-table/knockout.bootstraptable.js"></script> <script src="~/scripts/Department.js"></script>
都是一些常用的css和js檔案,我們自定義的js檔案主要有兩個: knockout.bootstraptable.js 和 Department.js 。上篇我們介紹過使用ko可以自定義我們的data-bind。同樣,這裡對於table的繫結,我們也定義一個自定義的繫結,程式碼 knockout.bootstraptable.js 裡面。
//新增ko自定義繫結 ko.bindingHandlers.myBootstrapTable = { init: function (element, valueAccessor, allBindingsAccessor, viewModel) { //這裡的oParam就是繫結的viewmodel var oViewModel = valueAccessor(); var $ele = $(element).bootstrapTable(oViewModel.params); //給viewmodel新增bootstrapTable方法 oViewModel.bootstrapTable = function () { return $ele.bootstrapTable.apply($ele, arguments); } }, update: function (element, valueAccessor, allBindingsAccessor, viewModel) {} }; //初始化 (function ($) { //向ko裡面新增一個bootstrapTableViewModel方法 ko.bootstrapTableViewModel = function (options) { var that = this; this.default = { search: true, //是否顯示錶格搜尋,此搜尋是客戶端搜尋,不會進服務端,所以,個人感覺意義不大 strictSearch: true, showColumns: true, //是否顯示所有的列 cache:false, showRefresh: true, //是否顯示重新整理按鈕 minimumCountColumns: 2, //最少允許的列數 clickToSelect: true, //是否啟用點選選中行 showToggle: true, }; this.params = $.extend({}, this.default, options || {}); //得到選中的記錄 this.getSelections = function () { var arrRes = that.bootstrapTable("getSelections") return arrRes; }; //重新整理 this.refresh = function () { that.bootstrapTable("refresh"); }; }; })(jQuery);
程式碼釋疑:這個js檔案主要做了兩件事
- 自定義data-bind屬性myBootstrapTable。對於ko.bindingHandlers.myBootstrapTable裡面的update方法,如非必須,可以不用定義。
- 通過向ko物件裡面新增bootstrapTableViewModel來封裝bootstrapTable。
1.2、html標籤啟動繫結
<table id="tb_dept" data-bind="myBootstrapTable:$root"> <thead> <tr> <th data-checkbox="true"></th> <th data-field="Name">部門名稱</th> <th data-field="Level">部門級別</th> <th data-field="Des">描述</th> <th data-field="strCreatetime">建立時間</th> </tr> </thead> </table>
程式碼釋疑:定義一個table標籤,使用自定義繫結myBootstrapTable,上篇說過,$root可以理解為初始化的意思。為了簡單,所有的colums就直接在<th>裡面寫了。
1.3、啟用ko的繫結
在頁面載入完成之後,啟動ko的繫結:
//初始化 $(function () { //1、初始化表格 tableInit.Init(); //2、註冊增刪改事件 operate.operateInit(); }); //初始化表格 var tableInit = { Init: function () { //繫結table的viewmodel this.myViewModel = new ko.bootstrapTableViewModel({ url: '/Department/GetDepartment', //請求後臺的URL(*) method: 'get', //請求方式(*) toolbar: '#toolbar', //工具按鈕用哪個容器 queryParams: function (param) { return { limit: param.limit, offset: param.offset }; },//傳遞引數(*) pagination: true, //是否顯示分頁(*) sidePagination: "server", //分頁方式:client客戶端分頁,server服務端分頁(*) pageNumber: 1, //初始化載入第一頁,預設第一頁 pageSize: 10, //每頁的記錄行數(*) pageList: [10, 25, 50, 100], //可供選擇的每頁的行數(*) }); ko.applyBindings(this.myViewModel, document.getElementById("tb_dept")); } };
程式碼釋疑:頁面載入完成之後,呼叫上面封裝的bootstrapTableViewModel物件合併傳遞的引數,最後啟用繫結,將this.myViewModel作為繫結的viewmodel啟用。除錯程式碼可知,當執行到 ko.applyBindings(this.myViewModel, document.getElementById("tb_dept")); 這一句的時候,自定義繫結才會生效,程式才會進入到 ko.bindingHandlers.myBootstrapTable 物件的init方法去初始化bootstrapTable。這裡需要說明一點:
init: function (element, valueAccessor, allBindingsAccessor, viewModel) { //這裡的oParam就是繫結的viewmodel var oViewModel = valueAccessor(); var $ele = $(element).bootstrapTable(oViewModel.params); //給viewmodel新增bootstrapTable方法 oViewModel.bootstrapTable = function () { return $ele.bootstrapTable.apply($ele, arguments); } }
上文中的init方法,通過第二個引數valueAccessor,我們得到的是當前繫結的viewmodel,也就是我們上面的this.myViewModel這個物件,博主覺得這一點有利於你理解自定義繫結的邏輯。基本上執行到 var $ele = $(element).bootstrapTable(oViewModel.params); 這一句的時候,我們表格的初始化就完成了。後臺對應的方法博主隨便定義了一個集合,為了完整,這裡還是貼出來:
public class DepartmentController : Controller { // GET: Department public ActionResult Index() { return View(); } [HttpGet] public JsonResult GetDepartment(int limit,int offset) { var lstRes = DepartmentModel.GetData(); lstRes.ForEach(x=> { x.strCreatetime = x.Createtime.ToString("yyyy-MM-dd HH:mm:ss"); }); var oRes = new { rows = lstRes.Skip(offset).Take(limit).ToList(), total = lstRes.Count }; return Json(oRes, JsonRequestBehavior.AllowGet); } [HttpPost] public JsonResult Add(Department oData) { DepartmentModel.Add(oData); return Json(new { }, JsonRequestBehavior.AllowGet); } [HttpPost] public JsonResult Update(Department oData) { DepartmentModel.Update(oData); return Json(new { }, JsonRequestBehavior.AllowGet); } [HttpPost] public JsonResult Delete(List<Department> oData) { DepartmentModel.Delete(oData); return Json(new { }, JsonRequestBehavior.AllowGet); } }DepartmentController
2、按鈕操作
上面通過bootstrapTable的初始化完成了我們的自定義data-bind的使用。下面的按鈕操作我們來體驗一把使用監控屬性的“爽歪歪”。
2.1、view頁面
首先在view頁面上面定義我們的增刪改按鈕
<div id="toolbar" class="btn-group"> <button id="btn_add" type="button" class="btn btn-default"> <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>新增 </button> <button id="btn_edit" type="button" class="btn btn-default"> <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>修改 </button> <button id="btn_delete" type="button" class="btn btn-default"> <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>刪除 </button> </div>
為了簡便,博主使用了一個隱藏的彈出框用來包含新增和編輯的文字框。當然,一般情況下,可能這裡用的是部分檢視,你的專案裡面可能會有一個Edit.cshtml,但這裡博主將這些都放在一個頁面上面,因為這不是文字的重點。
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title" id="myModalLabel">操作</h4> </div> <div class="modal-body"> <div class="form-group"> <label for="txt_departmentname">部門名稱</label> <input type="text" name="txt_departmentname" data-bind="value:Name" class="form-control" id="txt_departmentname" placeholder="部門名稱"> </div> <div class="form-group"> <label for="txt_departmentlevel">部門級別</label> <input type="text" name="txt_departmentlevel" data-bind="value:Level" class="form-control" id="txt_departmentlevel" placeholder="部門級別"> </div> <div class="form-group"> <label for="txt_des">描述</label> <input type="text" name="txt_des" data-bind="value:Des" class="form-control" id="txt_des" placeholder="描述"> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span>關閉</button> <button type="button" id="btn_submit" class="btn btn-primary" data-dismiss="modal"><span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span>儲存</button> </div> </div> </div> </div>
2.2、JS初始化按鈕操作
//操作 var operate = { //初始化按鈕事件 operateInit: function () { this.operateAdd(); this.operateUpdate(); this.operateDelete(); this.DepartmentModel = { id: ko.observable(), Name: ko.observable(), Level: ko.observable(), Des: ko.observable(), CreateTime: ko.observable() }; }, //新增 operateAdd: function(){ $('#btn_add').on("click", function () { $("#myModal").modal().on("shown.bs.modal", function () { var oEmptyModel = { id: ko.observable(), Name: ko.observable(), Level: ko.observable(), Des: ko.observable(), CreateTime: ko.observable() }; ko.utils.extend(operate.DepartmentModel, oEmptyModel); ko.applyBindings(operate.DepartmentModel, document.getElementById("myModal")); operate.operateSave(); }).on('hidden.bs.modal', function () { ko.cleanNode(document.getElementById("myModal")); }); }); }, //編輯 operateUpdate: function () { $('#btn_edit').on("click", function () { $("#myModal").modal().on("shown.bs.modal", function () { var arrselectedData = tableInit.myViewModel.getSelections(); if (!operate.operateCheck(arrselectedData)) { return; } //將選中該行資料有資料Model通過Mapping元件轉換為viewmodel ko.utils.extend(operate.DepartmentModel, ko.mapping.fromJS(arrselectedData[0])); ko.applyBindings(operate.DepartmentModel, document.getElementById("myModal")); operate.operateSave(); }).on('hidden.bs.modal', function () { //關閉彈出框的時候清除繫結(這個清空包括清空繫結和清空註冊事件) ko.cleanNode(document.getElementById("myModal")); }); }); }, //刪除 operateDelete: function () { $('#btn_delete').on("click", function () { var arrselectedData = tableInit.myViewModel.getSelections(); $.ajax({ url: "/Department/Delete", type: "post", contentType: 'application/json', data: JSON.stringify(arrselectedData), success: function (data, status) { alert(status); //tableInit.myViewModel.refresh(); } }); }); }, //儲存資料 operateSave: function () { $('#btn_submit').on("click", function () { //取到當前的viewmodel var oViewModel = operate.DepartmentModel; //將Viewmodel轉換為資料model var oDataModel = ko.toJS(oViewModel);var funcName = oDataModel.id?"Update":"Add"; $.ajax({ url: "/Department/"+funcName, type: "post", data: oDataModel, success: function (data, status) { alert(status); tableInit.myViewModel.refresh(); } }); }); }, //資料校驗 operateCheck:function(arr){ if (arr.length <= 0) { alert("請至少選擇一行資料"); return false; } if (arr.length > 1) { alert("只能編輯一行資料"); return false; } return true; } }
程式碼釋疑:說說這裡的執行邏輯,首先在$(function(){})方法裡面呼叫 operate.operateInit(); 。在operateInit()方法裡面註冊頁面上面按鈕的點選事件,同時也定義 this.DepartmentModel 作為我們新增編輯的viewmodel,這個viewmodel裡面定義了和頁面元素對應的監控屬性。還記得上面隱藏的彈出框裡面的一些data-bind嗎,沒錯,裡面對應的value值就是和這裡的監控屬性對應,這樣設定繫結之後,js裡面所有的導致 this.DepartmentModel 裡面監控的變化,都會觸發介面上面這些繫結標籤的value值變化,反之,介面上面的所有標籤的Value值的變化,也勢必會引起它的監控屬性值的變化,此之所謂雙向繫結。下面具體看看雙向繫結的執行。
2.3、新增操作
$('#btn_add').on("click", function () { $("#myModal").modal().on("shown.bs.modal", function () { var oEmptyModel = { id: ko.observable(), Name: ko.observable(), Level: ko.observable(), Des: ko.observable(), CreateTime: ko.observable() }; ko.utils.extend(operate.DepartmentModel, oEmptyModel); ko.applyBindings(operate.DepartmentModel, document.getElementById("myModal")); operate.operateSave(); }).on('hidden.bs.modal', function () { ko.cleanNode(document.getElementById("myModal")); }); });
當我們介面觸發新增操作的時候,首先會彈出上面說的隱藏模態框。在模態框顯示的時候,首先定義一個空的viewmodel,然後呼叫 ko.utils.extend(operate.DepartmentModel, oEmptyModel); 這一句,將全域性的operate.DepartmentModel被空的viewmodel覆蓋。ko.utils.extend()這個方法的作用和jquery裡面的$.extend()作用類似,都是根據後面物件合併前面物件,合併之後,使用新的viewmodel啟用繫結。啟用繫結之後,註冊儲存按鈕的click事件。這樣新增的時候,彈出模態框,由於viewmodel裡面的監控屬性都是空的,對應介面元素的value也會被清空,所以新增我們看到是這樣:
當彈出框關閉後,我們通過關閉的事件,執行 ko.cleanNode(document.getElementById("myModal")); 這一句,這個很重要,因為對於同一個dom,ko只能繫結一次,如果需要再次繫結,需要先清空繫結,並且cleanNode()這個方法,它不僅會清空繫結,還是會dom裡面註冊的事件也會清空,使用的時候需要注意下!
2.4、編輯操作
$('#btn_edit').on("click", function () { $("#myModal").modal().on("shown.bs.modal", function () { var arrselectedData = tableInit.myViewModel.getSelections(); if (!operate.operateCheck(arrselectedData)) { return; } //將選中該行資料有資料Model通過Mapping元件轉換為viewmodel ko.utils.extend(operate.DepartmentModel, ko.mapping.fromJS(arrselectedData[0])); ko.applyBindings(operate.DepartmentModel, document.getElementById("myModal")); operate.operateSave(); }).on('hidden.bs.modal', function () { //關閉彈出框的時候清除繫結(這個清空包括清空繫結和清空註冊事件) ko.cleanNode(document.getElementById("myModal")); }); });
當我們觸發編輯操作的時候,介面還是彈出框。在彈出框的彈出事件裡面,我們取到當前選中的行,然後校驗是否選中了一行。最好通過 ko.mapping.fromJS(arrselectedData[0]) 這一句,將普通的Json物件轉換為帶有監控屬性的viewmodel,上篇說過,這個方法需要 knockout.mapping-latest.js 這個js檔案的支援。轉換之後,還是通過ko.utils.extend()方法更新viewmodel,然後啟用繫結。由於viewmodel被當前選中行的資料更新了,所以得到結果:
2.5、儲存操作
在新增和編輯彈出框之後,修改相關資訊後點擊儲存,就會觸發儲存事件。
$('#btn_submit').on("click", function () { //取到當前的viewmodel var oViewModel = operate.DepartmentModel; //將Viewmodel轉換為資料model var oDataModel = ko.toJS(oViewModel); var funcName = oDataModel.id?"Update":"Add"; $.ajax({ url: "/Department/"+funcName, type: "post", data: oDataModel, success: function (data, status) { alert(status); tableInit.myViewModel.refresh(); } }); });
當觸發儲存事件的時候,我們首先取到頁面繫結的viewmodel,即operate.DepartmentModel,然後使用ko.toJS()方法將帶有監控屬性的viewmodel轉換為純資料的Json物件,這個方法是ko內建的,不需要其他js支援。得到json物件之後,傳送ajax請求,去新增或者編輯資料。這樣就很好地體現了雙向繫結,介面上面所有文字框的value發生了變化之後,也會觸發operate.DepartmentModel的變化。
2.6、刪除操作
刪除操作沒什麼好說的,和ko關係不大。
三、總結
以上通過一個簡單的增刪改查操作,介紹了下ko和bootstrapTable的聯合使用。ko可以讓你從DOM中解放出來,把關注點放在viewmodel上面。縱觀整個js程式碼,幾乎看不到jquery的val()、text()等對介面dom做取值和賦值的操作,是不是看著乾淨清爽,並且高大上了呢~~當然,這或許只是ko的一些比較基礎的用法,畢竟博主學習ko才3天,更多高階用法還有待摸索,等過段時間用熟了,再將它的一些高階用法分享給大家。如果你覺得本文能夠幫助你理解ko的原理以及它的一些用法,不妨推薦下,博主一定繼續努力!
相關推薦
JS元件系列——BootstrapTable+KnockoutJS實現增刪改查解決方案(二)
前言:上篇 JS元件系列——BootstrapTable+KnockoutJS實現增刪改查解決方案(一) 介紹了下knockout.js的一些基礎用法,由於篇幅的關係,所以只能分成兩篇,望見諒!昨天就覺得應該快點完成下篇,要不然有點標題黨的感覺,思及此,博主心有不安,於是加班趕出了下篇。如果你也打算用ko去做
JS元件系列——BootstrapTable+KnockoutJS實現增刪改查解決方案(一)
前言:出於某種原因,需要學習下Knockout.js,這個元件很早前聽說過,但一直沒嘗試使用,這兩天學習了下,覺得它真心不錯,雙向繫結的機制簡直太爽了。今天打算結合bootstrapTable和Knockout去實現一個簡單的增刪改查,來體驗一把神奇的MVVM。關於WebApi的剩餘部分,博主一定抽時間補上。
JS元件系列——BootstrapTable+KnockoutJS實現增刪改查解決方案(三):兩個Viewmodel搞定增刪改查
前言:之前博主分享過knockoutJS和BootstrapTable的一些基礎用法,都是寫基礎應用,根本談不上封裝,僅僅是避免了html控制元件的取值和賦值,遠遠沒有將MVVM的精妙展現出來。最近專案打算正式將ko用起來,於是乎對ko和bootstraptable做了一些封裝,在此分享出來供園友們參考。封裝
JS元件系列——BootstrapTable+KnockoutJS實現增刪改查解決方案(四):自定義T4模板快速生成頁面
前言:上篇介紹了下ko增刪改查的封裝,確實節省了大量的js程式碼。博主是一個喜歡偷懶的人,總覺得這些基礎的增刪改查效果能不能通過一個什麼工具直接生成頁面效果,啥程式碼都不用寫了,那該多爽。於是研究了下T4的語法,雖然沒有完全掌握,但是算是有了一個大致的瞭解,給需要自定義模板的園友們提供一個參考。於是乎有了今天
abp(net core)+easyui+efcore倉儲系統——展現層實現增刪改查之控制器(六)
abp(net core)+easyui+efcore倉儲系統目錄 abp(net core)+easyui+efcore倉儲系統——ABP總體介紹(一) abp(net core)+easyui+efcore倉儲系統——解決方案介紹(二) abp(net
unity網路實戰開發(叢林戰爭)-前期知識準備(011-c#連線資料庫並實現增刪改查以及sql注入問題)
使用工具:VS2015,Mysql使用語言:c#作者:Gemini_xujian參考:siki老師-《叢林戰爭》視訊教程繼上一篇文章內容,這節課講解一下資料庫的前期連線準備以及通過c# 實現資料庫的增刪改擦操作。首先你需要自行安裝Mysql以及它的workbench元件。然後
springboot+jpa+thymeleaf增刪改查的示例(轉)
fse 生效 with sources set ide horizon prop table 這篇文章介紹如何使用jpa和thymeleaf做一個增刪改查的示例。 先和大家聊聊我為什麽喜歡寫這種腳手架的項目,在我學習一門新技術的時候,總是想快速的搭建起一個demo來試試它
BS(三層)—增刪改查——Web窗體(aspx)版本
上一篇我們用一般處理程式寫了(ashx)寫了一遍增刪改查,今天我們將用Web窗體(aspx)寫一遍增刪改查。我們平時寫的時候到底用一般處理程式呢?還是用Web窗體呢? 簡單來說web窗體(aspx)是一般處理程式(ashx)的一個複雜版本
SSM 實訓筆記 -12- 開源 Spring+Spring MVC+JDBC Template 增刪改查 前期專案(maven)
SSM 實訓筆記 -12- 開源 Spring+Spring MVC+JDBC Template 增刪改查 前期專案(maven) 實訓前期小專案,大佬勿笑 僱員資訊管理系統 2019-01-11 專案簡介: 內容: Spring + Spring MVC
【pandas】[2] DataFrame 基礎,建立DataFrame和增刪改查基本操作(1)
作者:lianghc 地址:http://blog.csdn.net/zutsoft DataFrame 是pandas最常用的資料結構,類似於資料庫中的表,不過DataFrame不僅僅限制於2維,可以建立多維資料表。DataFrame既有行索引,也有列
Mock.js簡易教程,脫離後端獨立開發,實現增刪改查功能
定義 數據 false 則表達式 type break 整數 增 刪 改 查 大於 在我們的生產實際中,後端的接口往往是較晚才會出來,並且還要寫接口文檔,於是我們的前端的許多開發都要等到接口給我們才能進行,這樣對於我們前端來說顯得十分的被動,於是有沒有可以制造假數據來模擬後
spring-boot react一步一步實現增刪改查 元件化
在 spring-boot react一步一步實現增刪改查 中,用一個元件實現了表格和表單功能,所以現在需要將其拆分成元件獨立出來 拆分表格 建立Table.js import React, {Component} from 'react' class Tab
JS元件系列——BootstrapTable 行內編輯解決方案:x-editable
前言:之前介紹bootstrapTable元件的時候有提到它的行內編輯功能,只不過為了展示功能,將此一筆帶過了,罪過罪過!最近專案裡面還是打算將行內編輯用起來,於是再次研究了下x-editable元件,遇到過一些坑,再此做個採坑記錄吧!想要了解bootstrapTable的園友可以移步 JS元件系列——表格元
ABP入門系列(5)——展現層實現增刪改查
這一章節將通過完善Controller、View、ViewModel,來實現展現層的增刪改查。最終實現效果如下圖: 一、定義Controller ABP對ASP.NET MVC Controllers進行了整合,通過引入Abp.Web.Mvc名稱空間,建立Controller繼承自AbpControlle
Spring Boot入門系列(六)如何整合Mybatis實現增刪改查
前面介紹了Spring Boot 中的整合Thymeleaf前端html框架,同時也介紹了Thymeleaf 的用法。不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/zhangweizhong/category/1657780.html。 今天主要講解Springboot整合M
Spring Boot入門系列(十八)整合mybatis,使用註解的方式實現增刪改查
之前介紹了Spring Boot 整合mybatis 使用xml配置的方式實現增刪改查,還介紹了自定義mapper 實現複雜多表關聯查詢。雖然目前 mybatis 使用xml 配置的方式 已經極大減輕了配置的複雜度,支援 generator 外掛 根據表結構自動生成實體類、配置檔案和dao層程式碼,減輕很大一
修改Haproxy文件配置,實現增刪改查
文件配置 str data bin 都是 [1] local def onf Haproxy 源文件 global log 127.0.0.1 local2 daemon maxconn 256 log 12
[python] 用pickle模塊實現“增刪改查”的簡易功能
python pyckle模塊 #!/usr/bin/env python2 #coding:utf-8 """ pickle的作用: 1:pickle.dump(dict,file)把字典轉為二進制存入文件. 2:pickle.load(file)把文件二進制內容轉為字典. """ im
.NET EF 框架-實現增刪改查
ont int string dbcontext 增刪 base set cts cti 聲明一個EF上下文對象 Model dbContext=new Model(); 添加操作(向表中插入一條數據) //聲明一個表的實體 Contact contact =new Con
作業員工信息表實現增刪改查操作
nbsp 手機號 add bre mark 作業 ket split 格式不正確 有以下員工信息表 當然此表你在文件存儲時可以這樣表示 1 1,Alex Li,22,13651054608,IT,2013-04-01 現需要對這個員工