Knockoutjs هو إطار MVVM من جافا سكريبت. جيد جدًا. على سبيل المثال ، بعد إضافة أو تقليل عناصر بيانات القائمة ، ليست هناك حاجة لتحديث جزء التحكم بأكمله أو كتابة عقد الإضافة وحذف JS بنفسك. فقط حدد القالب والسمات التي تلبي تعريفات بناء الجملة. ببساطة ، نحتاج فقط إلى الانتباه إلى الوصول إلى البيانات.
1. مقدمة
نظرًا لأن نظام الشركة يحتاج إلى تجديده مؤخرًا ، أخطط لاستخدام KnockoutJs لإنشاء واجهة أمامية على شبكة الإنترنت للنظام الجديد الذي تم تجديده. أثناء العملية ، واجهت مشكلة - كيفية استخدام KnockoutJs لإكمال وظيفة ترقيم الصفحات. في المقالة السابقة ، لا يتم تقديم KnockOutJs لتنفيذ ترقيم الصفحات ، لذلك في هذه المقالة ، سيتم استخدام bootstrap straintjs + bootstrap لتنفيذ عرض ترقيم الصفحات.
2. استخدم Knockoutjs لتنفيذ ترقيم الصفحات
هناك طريقتان لتنفيذ الترحيل. الأول هو تحميل جميع البيانات ثم عرض جميع البيانات على الصفحات ؛ والثاني هو تحميل جزء فقط من البيانات في كل مرة ، وإعادة تحميل البيانات اللاحقة في كل مرة.
بالنسبة لهاتين الطريقتين ، يعتمد ترقيم الصفحات باستخدام طريقة Razor بشكل عام الطريقة الثانية لتنفيذ ترقيم الصفحات ، ولكن بالنسبة للبرامج ذات الصفحات الواحدة ، فإن التنفيذ الأول له فوائده أيضًا. بالنسبة لكميات كبيرة جدًا من البيانات ، يمكن استخدام طريقة التنفيذ الأولى ، لأنه بهذه الطريقة ، سيكون تحميل البيانات اللاحق سلسًا للغاية. لذلك سنقدم هنا طريقتي التنفيذ بشكل منفصل.
2.1 تنفيذ تحميل البيانات الجزئية في كل مرة
يستخدم رمز الواجهة الخلفية هنا الرمز من المقالة السابقة ، ولكنه يضيف بعض بيانات المثال. رمز تنفيذ الواجهة الخلفية المحددة هو:
/// <summary> /// Web API Service ، وتوفير خدمات البيانات لـ Web Front-end /// </summary> فئة عامة TaskController: apicontroller {private readOnly TaskRepository _TaskRepository = taskRepository.current ؛ public ienumerable <Task> getAll () {return _taskRepository.getAll (). orderby (a => A.ID) ؛ } [Route ("API/Task/GetBypated")] pagedmodel getall ([fromuri] int pageIndex) {const int pagesize = 3 ؛ int totalCount ؛ VAR CASKS = _TASKREPOSTORY.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} ؛ // إرجاع بيانات إرجاع PageSta ؛ }} /// <summary> /// مستودع المهام ، يتغلف جميع العمليات حول قاعدة البيانات /// </summary> الفئة العامة TaskRepository {#Region Static Static Filed Private Static STATIC STATIC LAZINGERISTORY> _TaskRepository = New LazyRepository> (() =) Public Static TaskRepository Current {get {return _taskrepository.value ؛ }}} #endregion #region fields private readonly list <Task> _tasks = new list <Task> () {new Task {id = 1 ، name = "Create a Spa Program dateTime.parse (dateTime.now.addDays (1) .ToString (CultureInfo.InvariantCulture))} ، مهمة جديدة {id = 2 ، name = "Learning jrokenoutjs" ، description = "straintjs is عبارة dateTime.parse (dateTime.now.addDays (2) .ToString (CultureInfo.InvariantCulture))} ، مهمة جديدة {id = 3 ، name = "Learn AngularJs" ، description = "AngularJS هو إطار MVVM الذي يدمج mvvm و mvc مع واحد. dateTime.Parse (dateTime.now.addDays (3) .ToString (CultureInfo.InvariantCulture))} ، مهمة جديدة {id = 4 ، name = "تعلم ASP.NET MVC موقع" ، الوصف = "لمحة هو أداة اختبار الأداء تحت .NET ، والتي تدعم asp.net ، كما هو مميز ، رمز المشروع الأصلي ، ويمكنه إخراج وقت تنفيذ كل رابط لتنفيذ الكود "، owner =" tonny li "، finishtime = dateTime.parse (dateTime.now.adddays (4) .ToString (intreenfo.invariantculture))} ، مهمة جديدة {id = 5 ، اسم المهمة 1" dateTime.Parse (dateTime.now.addDays (5) .ToString (CultureInfo.InvariantCulture))} ، مهمة جديدة {id = 6 ، name = "Test Task 2" ، Description = "Test Task 2" ، owner = "li Zhi" dateTime.Parse (dateTime.now.addDays (6) .ToString (CultureInfo.InvariantCulture))} ، مهمة جديدة {id = 7 ، name = "Test Task 3" ، Description = "Test Task 3" dateTime.parse (dateTime.now.adddays (7) .ToString (CultureInfo.InvariantCulture))} ،} ؛ #endregion #region الأساليب العامة العامة ienumerable <Task> getAll () {return _tasks ؛ } ienumerable <Task> getall (int pagenumber ، int pagesize ، out int totalCount) {var skip = (pagenumber - 1) * pagesize ؛ var take = pagesize ؛ TotalCount = _tasks.count ؛ return _tasks.skip (Skip) .Take (take) ؛ } المهمة العامة GET (int id) {return _tasks.find (p => p.id == id) ؛ } إضافة المهمة العامة (عنصر المهمة) {if (item == null) {رمي new argumentNullexception ("item") ؛ } item.id = _tasks.count + 1 ؛ _tasks.add (عنصر) ؛ عنصر الإرجاع ؛ } public void remove (int id) {_tasks.removeall (p => p.id == id) ؛ } تحديث Bool Public (عنصر المهمة) {if (item == null) {رمي new argumentNullexception ("item") ؛ } 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> طريقة التنفيذ الثانية لقائمة ترقيم الصفحات </h2> <viv> <div> Charge </h> <th> وقت الإنشاء </th> <th> الوقت الكامل </th> <th> الحالة </th> </tr> </preat> <tbody data-bind = "foreach: pagedlist"> <tr> <td data-bind = "text: id" الوصف "> </td> <td data-bind =" text: owner "> </td> <td data-bind =" text: createTime "> </td> <td data-bind =" text: finishtime "> </td> <td data-bind =" text: state "> colspan = "8"> <img src = "/images/loading.gif"/> </td> </tbody> <tfood <tfoot data-bind = "ifnot: loadingState"> <tr> <td colspan = "8" data-bind = "text: pagesize"> </span> السجلات </div> <viv> <ul> <li data-bind = "css: {upabled: pageIndex () === 1}"> <a href = "#" data-bind = "click: previp"> «</a> </li> <ul> <ul> $ data.pagenumber === ($ root.pageindex ())} "> <a href ="#"data-bind =" text: $ data.pagenumber ، انقر فوق: function () {$ root.gotopage ($ data.pagenber) ؛ pageCount} "> <a href ="#"data-bind =" click: next ">» </a> </li> </ul> </viv> </viv> </td> </tfoot> </table> </viv> </viv>تطبيق JS المقابل هو:
// الطريقة الثانية لتنفيذ paging var listViewModel2 = function () {// viewModel نفسها. تستخدم لمنع الارتباك النطاق عند استخدام هذا var self = this ؛ self.loadingState = ko.Observable (true) ؛ self.pagesize = ko.observable (3) ؛ // data this.pagedlist = ko.observablearray () ؛ // رقم الصفحة المراد الوصول إليه Ko.ObservableArray () ؛ // الصفحة الحالية this.currengePage = ko.Observable (1) ؛ self.totalcount = ko.observable (1) ؛ this.refresh = function () {// تقييد رقم صفحة الطلب ضمن رقم صفحة البيانات إذا (self.pageIndex () <1) self.pageindex (1) ؛ if (self.pageindex ()> self.pagecount () SendaaxRequest ("get" ، الوظيفة (البيانات) {// قبل تحميل البيانات الجديدة ، قم بإزالة البيانات الأصلية self.pagedlist.removeall () ؛ self.allpages.removeall () ؛ self.totalCount (data.totalCount) ؛ self.pagecount (data.pagecount) ؛ i ++) {// رقم صفحة إعادة التحميل. data self.pagedlist.push (data.pagedData [i]) ؛}} ، 'getBypaged' ، {'pageIndex': self.pageIndex ()}) ؛} ؛ {self.pageIndex (this.pageIndex () + 1) ؛ self.refresh () ؛} ؛ // اطلب الصفحة السابقة للبيانات this.previous = function () {self.pageindex (this.pageindex () - 1) ؛ self.refresh () ؛ 1 ؛ وظيفة sendajaxRequest (httpmethod ، رد الاتصال ، url ، reqdata) {$ .ajax ("/api/task" + (url؟ "/" + url: "") ، {type: httpmethod ، success: callback ، data: reqdata}) ؛ ListViewModel2 () ؛ viewmodel.refresh () ؛ if ($ ('#list2'). length) ko.applybindings (viewModel ، $ ('#list2'). get (0)) ؛}) ؛فيما يلي مقدمة لفكرة التنفيذ المتمثلة في استخدام knockoutjs لتنفيذ وظيفة ترقيم الصفحات:
1. بعد تحميل الصفحة ، ابدأ طلب AJAX للاتصال بخدمة REST بشكل غير متزامن لطلب جزء من البيانات.
2. ثم عرض البيانات المطلوبة من خلال ارتباط knockoutjs.
3. ربط معلومات الترحيل المقابلة إلى ترحيل bootstrap
4. عندما ينقر المستخدم على تشغيل الصفحة ، قم ببدء طلب AJAX للاتصال بخدمة REST بشكل غير متزامن وعرض البيانات المطلوبة.
هذه هي العلاقة المنطقية لرمز الاتصال الموضح أعلاه. يمكنك الرجوع إلى رمز JS المقابل لفهم الوصف أعلاه. في هذه المرحلة ، تم الانتهاء من طريقة التنفيذ الثانية لدينا.
2.2 قم بتحميل جميع البيانات لأول مرة ، ثم عرض جميع ترحيل البيانات
بعد ذلك ، سنقدم طريقة التنفيذ الأولى. في طريقة التنفيذ هذه ، سيشعر المستخدمون فقط أن البيانات يتم تحميلها لأول مرة ، ولن يشعروا بتحميل الصفحة أثناء عملية تحول الصفحة. هذا سيجعل المستخدمين يشعرون أكثر سلاسة عندما لا يكون هناك الكثير من البيانات في بعض الحالات.
تتمثل فكرة التنفيذ المحددة في عدم عرض جميع البيانات المطلوبة على الصفحة ، لأن هناك الكثير من البيانات وسيتم عرضها على الصفحة في وقت واحد ، وقد يتم إبهار المستخدمين. عرض ترحيل البيانات سيجعل المستخدمين عرضًا أكثر وضوحًا.
رمز التنفيذ المحدد لـ Web Front JS هو:
var listViewModel = function () {var self = this ؛ window.viewmodel = 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 (start ، start + size) ؛ 1 ، 1) ؛}} ؛ self.allpages = ko.dependentObservable (function () {var pages = [] ؛ for (var i = 0 ؛ i <= self.maxpageIndex () ؛ i ++) {pages.push ({pagenumber: (i+1)}) ؛ {self.pageIndex (index) ؛} ؛} ؛ var listViewModel = new listViewModel () ؛ function bindViewModel () {sendajaxRequest ("get" ، function (data) {listViewModel.loadingState (falsa) ؛ listViewModel.List (data) ؛ ($ ('#list'). length) ko.applyBindings (listViewModel ، $ ('#list'). get (0)) ؛} ، null ، null) ؛} $ (document) .Ready (function () {bindViewModel () ؛}) ؛يشبه تنفيذ صفحتها الأمامية التنفيذ السابق. رمز الصفحة المحدد كما يلي:
@{viewbag.title = "index" ؛ lyout = "~/views/shared/_layout.cshtml" ؛} <div id = "list" الوقت </th> <th> وقت الانتهاء </th> <th> Statu </h> </tbor> </tbody data-bind = "foreach: pagedlist"> <tr> <td data-bind = "text: id" data-bind = "text: owner"> </td> <td data-bind = "text: createTime"> </td> <td data-bind = "text: finishtime"> </td> <td data-bind = "text: state"> </td> </tbod src = "/images/loading.gif"/> </td> </tbor> </tbody> <tfoot data-bind = "ifnot: loadingState"> <tr> <td colspan = "8" Pagesize "> </span> سجلات </div> <viv> <ul> <li data-bind =" css: {upabled: pageIndex () === 0} "> <a href ="#"data-bind =" click: previour page ">« </a> </li> </ul> <ul data-bind = "for allpages"> $ data.pagenumber === ($ root.pageIndex () + 1)} "> <a href ="#"data-bind =" text: $ data.pagenumber ، انقر فوق: function () {$ root.movetopage ($ data.pagenber-1) ؛ === MaxPageIndex ()} "> <a href ="#"data-bind =" click: nextpage ">» </a>3. تأثير التشغيل
بعد ذلك ، دعونا نلقي نظرة على تأثير ترقيم الصفحات الذي تم تنفيذه باستخدام Knockoutjs:
4. ملخص
في هذه المرحلة ، انتهى المحتوى الذي سيتم تقديمه في هذه المقالة. على الرغم من أن المحتوى الذي تم تنفيذه في هذه المقالة بسيط نسبيًا ، بالنسبة لبعض الأصدقاء الجدد في Knockoutjs ، أعتقد أن تنفيذ هذه المقالة سيكون الكثير من التوجيهات. بعد ذلك ، سوف أشارككم المحتوى ذي الصلة من AngularJS.
ما سبق هو شرح مفصل لأمثلة الجمع بين bootstrap مع knockoutjs لتحقيق تأثيرات ترقيم الصفحات التي قدمها لك المحرر. آمل أن يكون ذلك مفيدًا لك!