Knockoutjs는 JavaScript에서 구현 된 MVVM 프레임 워크입니다. 매우 좋은. 예를 들어, 목록 데이터 항목을 추가하거나 줄인 후에 전체 컨트롤 조각을 새로 고치거나 JS 추가 및 삭제 노드를 직접 작성할 필요가 없습니다. 구문 정의를 충족하는 템플릿과 속성 만 정의하십시오. 간단히 말해서, 우리는 데이터에 대한 액세스에만주의를 기울이면됩니다.
1. 소개
최근 회사의 시스템을 개선해야하므로 Knockoutjs를 사용하여 개조 된 새 시스템을위한 웹 프론트 엔드를 만들 계획입니다. 그 과정에서 나는 Knockoutjs를 사용하여 Pagination 기능을 완료하는 방법에 직면했습니다. 이전 기사에서는 Knockoutjs가 Pagination을 구현하기 위해 소개되지 않으므로이 기사에서는 Knockoutjs + Bootstrap을 사용하여 데이터의 페이지 화 디스플레이를 구현합니다.
2. Knockoutjs를 사용하여 Pagination을 구현하십시오
페이징을 구현하는 두 가지 방법이 있습니다. 첫 번째는 모든 데이터를로드 한 다음 페이지에 모든 데이터를 표시하는 것입니다. 두 번째는 매번 데이터의 일부만로드하고 매번 후속 데이터를 다시로드하는 것입니다.
이 두 가지 방법의 경우 Razor 메소드를 사용하여 구현 된 페이지 매김은 일반적으로 Pagination을 구현하기위한 두 번째 방법을 채택하지만 단일 페이지 프로그램의 경우 첫 번째 구현에도 그 이점이 있습니다. 많은 양의 데이터가 아닌 경우, 첫 번째 구현 방법을 사용할 수 있습니다. 이러한 방식으로 후속 데이터로드가 매우 매끄럽기 때문입니다. 따라서이 두 구현 방법을 개별적으로 소개합니다.
2.1 매번 부분 데이터로드 구현
여기서 백엔드 코드는 이전 기사의 코드를 사용하지만 일부 예제 데이터를 추가합니다. 특정 백엔드 구현 코드는 다음과 같습니다.
/// <summary> /// Web API 서비스, 웹 프론트 엔드에 대한 데이터 서비스 제공 /// </summary> public class taskcontroller : apicontroller {private readonly taskrepository _taskRepository = taskrepository.current; public ienumerable <asking> getall () {return _taskrepository.getall (). Orderby (a => a.id); } [Route ( "API/TASK/GETBYPADED")] 공개 PAGEDMODEL getAll ([FromUri] int pageIndex) {const int pagesize = 3; int totalcount; var tasks = _taskRepository.getall (pageIndex, pagesize, out totalCount) .OrderBy (a => a.id); var pagedata = new pagedModel () {pageIndex = pageIndex, pagedData = tasks.tolist (), TotalCount = TotalCount, pageCount = (TotalCount+ pagesize -1) / pagesize}; // 반환 데이터 반환 PAGEDATA; }} /// <summary> /// task Repository, 데이터베이스에 대한 모든 작업을 캡슐화하는 /// </summary> 공개 클래스 taskRepository { #Region STATIN STATIC STATIC LAZY <TASKREPOSITORY> _TASKRepository = new Lazy <taskRepository> (() => new taskrepository ()); public static taskrepository current {get {return _taskrepository.value; }}} #endregion #region fields 개인 readonly list <atoding> _tasks = new List <aveSt> () {new Task {id = 1, name = "spa 프로그램 만들기", description = "Spa (단일 페이지 웹 응용 프로그램), 스파의 장점은 소량의 대역폭 및 매끄러운 경험", 소유자 = "하드 홀드 =" datetime.parse (datetime.now.adddays (1) .tostring (culture (cultureinfo.invariantculture))}, new task {id = 2, name = "learning knockoutjs", description = "knockoutjs는 양방향 바인딩을 지원하는 mvvm 클래스 라이브러리입니다. datetime.parse (datetime.now.adddays (2) .toString (cultureInfo.invariantculture))}, new task {id = 3, name = "warm angularjs", description = "angularjs는 mvvm과 mvc를 하나와 통합하는 mvvm 프레임 워크입니다. datetime.parse (datetime.now.adddays (3) .tostring (cultureNfo.invariantculture))}, new task {id = 4, name = "charn asp.net mvc 웹 사이트", description = "glimpse는 asp.net, asp.net mvc, asp.net mvc, ef를 지원하는 성능 테스트 도구입니다. 프로젝트 및 코드 실행의 각 링크 실행 시간을 출력 할 수 있습니다. datetime.parse (datetime.now.adddays (5) .toString (CultureInfo.invariantculture))}, new Task {id = 6, name = "test task 2", description = "test task 2", "li zhi", finishtime = datetime.parse (datetime.now.adddays (6) .tostring (cultureNfo.invariantculture))}, new Task {id = 7, name = "test task 3", description = "test task 3", "li zhi", finishtime = dateTime.parse (dateTime.now.adddays (7) .ToString (CultureInfo.InvariantCulture))},}; #endregion #region public methods public ienumerable <asking> getall () {return _tasks; } public ienumerable <asking> getall (int pagenumber, int pagesize, unt totalcount) {var skip = (pagenumber -1) * pagesize; var take = pagesize; TotalCount = _tasks.count; 반환 _tasks.skip (skip) .take (take); } 공개 작업 get (int id) {return _tasks.find (p => p.id == id); } public task add (작업 항목) {if (item == null) {throw new argumentNullexception ( "Item"); } item.id = _tasks.count + 1; _tasks.add (항목); 반품 항목; } public void remove (int id) {_tasks.removeall (p => p.id == id); } public bool update (작업 항목) {if (item == null) {새로운 ArgumentNullexception ( "항목"); } var taskitem = get (item.id); if (taskitem == null) {return false; } _tasks.remove (taskItem); _tasks.add (항목); 진실을 반환하십시오. } #endregion}웹 프론트 엔드 구현 코드 :
@{viewbag.title = "index2"; layout = "~/views/shared/_layout.cshtml";} <div id = "list2"> <h2> Pagfination-<Thead의 두 번째 구현 방법 </h2> <div> <Thead> <t> <Th> <th> name </th> <Thon> <Thon> Charge </th> <th> Creation Time </th> <th> 완전 시간 </th> <th> 상태 </th> <th> status </th> </tr> </treat> <tbody data-bind = "foreach : pagedlist"> <tr> <td data-bind = "text : id"> </td> <td> <a data-bind = "text : </a> <td> </a> 설명 "> </td> <td data-bind ="text : 소유자 "> </td> <td data-bind ="text : creationtime "> </td> <td data-bind ="text : finishtime "> </td> <td data-bind ="text : state "> </td> </td> <tbody-bind ="if : : doadeState : hoadeing : colspan = "8"> <img src = "/images/loading.gif"/> </td> </tr> </tbody> <tfoot data-bind = "ifnot : loadingstate"> <tr> <td colspan = "8"> <div> <div> <span data-bind = "tattcount"> </span records, <div> <div> </span records : < data-bind = "text : pagesize"> </span> 레코드 </div> <li> <li data-bind = "css : {disabled : {pageindex () === 1}"> <a href = "#"data-bind = "click : previous">«</a> </li> </ul> <ul data-bind = "foreach : <li data-bind"> $ data.pagenumber === ($ root.pageIndex ())} "> <a href ="#"data-bind ="text : $ data.pagenumber, click : function () pagecount} "> <a href ="#"#"data-bind = "click : next">»</a> </li> </ul> </div> </div> </td> </tfoot> </div> </div>해당 JS 구현은 다음과 같습니다.
// 페이징 var listViewModel2 = function () {// viewModel 자체를 구현하는 두 번째 방법. 이 직접 var self = this를 사용할 때 범위 혼란을 방지하는 데 사용됩니다. self.loadingstate = ko.observable (true); self.pagesize = ko.observable (3); // data this.pagedlist = ko.observablearray (); // 액세스 할 페이지 번호 this. ko.observablearray (); // 현재 페이지 this.currengepage = ko.observable (1); self.totalCount = ko.Observable (1); this.refresh = function () {// 데이터 페이지 번호 내에서 요청 페이지 번호를 제한합니다. if (self.pageIndex () <1) self.pageIndex (1); if (self.pageIndex ()> self.pagecount ()) {self.pageIndex (self.pageIndex ()); sendajaxRequest ( "get", function (data) {// 새 데이터를로드하기 전에 원본 데이터를 제거하기 전에 self.pagedlist.removeall (); self.allpages.removeall (); self.totalCount (data.totalCount); self.pagecount (data.pagecount); var i = 1; i ++) {// page number self.allpages.push ({pagenumber : i});} // ... in ... in in ...에서 .... 데이터의 요소에서 작동 할 때마다 self.pagedlist.push (data.pagedData [i]);}}, 'getByped', { 'pageIndex': self.pageIndex ()});}; // 데이터의 첫 페이지를 요청 this.first = function () {self.pageIndex (1); self.refresh (};); {self.pageIndex (this.pageIndex () + 1); self.refresh ();}; // 이전 페이지의 이전 페이지를 요청하십시오 .previous = function () {self.pageIndex (this.pageIndex () - 1); self.refresh (); // data의 마지막 페이지를 요청합니다. 1); self.refresh ();}; // 특정 페이지로 리디렉션 this.gotopage = function (data, event) {self.pageindex (data); self.refresh ();};}; 함수 sendajaxRequest (httpMethod, 콜백, url, reqdata) {$ .ajax ( "/api/task" + (url? "/" + url : ""), {type : httpmethod, success : 콜백, data : reqdata});} $ (var view). listViewModel2 (); viewModel.Refresh (); if ($ ( '#list2'). length) ko.applyBindings (ViewModel, $ ( '#list2'). get (0));});다음은 Knockoutjs를 사용하여 Pagination 기능을 구현한다는 구현 아이디어에 대한 소개입니다.
1. 페이지가로드 된 후에는 AJAX 요청을 시작하여 나머지 서비스를 비동기 적으로 호출하여 데이터의 일부를 요청하십시오.
2. 그런 다음 Knockoutjs 바인딩을 통해 요청 된 데이터를 표시합니다.
3. 해당 페이징 정보를 부트 스트랩 페이징에 바인딩합니다.
4. 사용자가 페이지를 돌리기 위해 클릭하면 AJAX 요청을 시작하여 나머지 서비스를 비동기로 호출하고 요청 된 데이터를 표시합니다.
이것은 위에서 설명한 호출 코드의 논리적 관계입니다. 위의 설명을 이해하려면 해당 JS 코드를 참조 할 수 있습니다. 이 시점에서 두 번째 구현 방법이 완료되었습니다.
2.2 모든 데이터를 처음으로로드 한 다음 모든 데이터 페이징을 표시합니다.
다음으로 첫 번째 구현 방법을 소개합니다. 이 구현 방법에서 사용자는 데이터가 처음으로로드되고 있다고 생각하며 페이지 회전 프로세스 중에 페이지로드를 느끼지 않습니다. 이렇게하면 경우에 따라 데이터가 너무 많지 않으면 사용자가 더 부드럽게 느껴집니다.
특정 구현 아이디어는 데이터가 너무 많고 페이지에 한 번에 페이지에 표시되며 사용자가 현혹 될 수 있으므로 페이지에 요청 된 모든 데이터를 표시하지 않는 것입니다. 데이터 페이징을 표시하면 사용자가 더 명확하게 볼 수 있습니다.
웹 프론트 엔드 JS의 특정 구현 코드는 다음과 같습니다.
var listViewModel = function () {var self = this; window.viewModel = self; self.list = ko.observablearRay (); self.pagesize = ko.observable (3); self.pageindex = ko.observable (0); // 액세스 할 페이지 번호는 self.totalCount = ko.Observable (1); // 총 레코드 수 Self.LoadingState = ko.Observable (true); self.pagedlist = ko.dependentObservable (function () {var size = self.pagesize (); var start = self.pageindex () * size; return self.list.slice (시작, 시작 + 크기);}); maxPageIndex = ko.dependentObservable (function () {self.lost ()). 1;}); self.previousPage = function () {if (self.pageIndex ()> 0) {self.pageIndex (self.pageIndex () -1);}}; self.nextPage = function () {if (self.pageIndex () {self.pageIndex (self.pageIndex ()) { 1);}}; self.allpages = ko.dependentObservable (function () {var pages = []; for (var i = 0; i <= self.maxpageindex (); i ++) {pages.push ({pagenumber : (i+1)});} pages;}); self.movetopage =) {self.pageIndex (index);};}; var listViewModel = new ListViewModel (); function bindViewModel () {sendajaxRequest ( "get", function (data) {listViewModel.LoadingState (false); listViewModel.List (data); ($ ( '#list'). length) ko.applybindings (listViewModel, $ ( '#list'). get (0));}, null, null);} $ (document) .ready (function () {bindViewModel ();});프론트 엔드 페이지의 구현은 이전 구현과 유사합니다. 특정 페이지 코드는 다음과 같습니다.
@{viewbag.title = "index"; layout = "~/views/shared/_layout.cshtml";} <div id = "list"> <h2> 작업 목록 </h2> <div> <table> <traad> <tr> <th> </th> <th> name <th> deplection </th> <Th> <Th> <Th> <Th> 시간 </th> <th> 완료 시간 </th> <th> statu </th> </tr> </tbody-bind = "foreach : pagedList"> <tr> <td data-bind = "text : id"> </td> <td> <data-bind = "text : name"> </a> </td> <td data-bind = </td> <td data-bind = "text : onder"> </td> <td data-bind = "text : creationtime"> </td> <td data-bind = "text : finishtime"> </td> <td data-bind = "text : state"> </td> </tbody> <tbody> <tbody> <tbody> <tbody> bind = "if : loadingstate"> src = "/images/loading.gif"/> </td> </tt> </tbody> <tfoot data-bind = "ifnot : loadingstate"> <tr> <td colspan = "8"> <div> <div> <span data-bind = "total count : </span> 레코드의 총계가 있습니다. 레코드 </div> <div> <ul> <li data-bind = "css : {disabled : pageindex () === 0}"> <a href = "#"data-bind = "click : previousepage">«</a> </li> </li> </ul> <ul data-bind = "foreach : allpages"> ($ root.pageIndex () + 1)} "> <a href ="#"data-bind ="text : $ data.pagenumber, click : function () {$ root.movetOpage ($ data.pagenumber-1); } "> <a href ="#"data-bind ="click : nextPage ">»</a> </a> </li> </ul> </div> </div> </td> </tfoot> </table> </tiv> </div>3. 작동 효과
다음으로 Knockoutjs를 사용하여 구현 된 페이지 매김 효과를 살펴 보겠습니다.
4. 요약
이 시점 에서이 기사에서 소개 할 내용은 끝났습니다. 이 기사에서 구현 된 내용은 비교적 간단하지만 Knockoutjs를 처음 접하는 일부 친구들의 경우이 기사의 구현은 많은 지침이 될 것이라고 생각합니다. 다음으로 AngularJS의 관련 내용을 여러분과 공유하겠습니다.
위의 내용은 부트 스트랩을 Knockoutjs와 결합하여 편집자가 소개 한 페이지 매김 효과를 달성하는 예에 대한 자세한 설명입니다. 나는 그것이 당신에게 도움이되기를 바랍니다!