English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

تحليل مشكلة تحقيق التلميحات الخاطئة باستخدام jquery.validate[.unobtrusive] وBootstrap

هناك مقالات مشابهة، راجعها هنا، أعتقد أن بعضها معقد، وأنا أيضًا كنت أرغب في كتابة واحد بسيط يستخدم في المشروع، وأنا سأقوم بتحرير النقاط الأساسية هنا. النتيجة النهائية ستكون مثل هذا:

في الخلفية يستخدم Asp.net mvc5، وفي الواجهة الأمامية يستخدم إطارات العمل مثل: jquery.validate،jquery.validate.unobtrusive،requirejs،Bootstrap، جميعها من الإصدارات الأحدث. لا تحتاج إلى الحديث عن jquery.validate، إنه مكون التحقق الأمامي الشائع حاليًا؛ jquery.validate.unobtrusive يعتمد على jquery.validate، ويُكتب لتناسب Asp.net mvc، تم كتابته من قبل Microsoft، يمكنك العثور عليه في NuGet تحت اسم Microsoft.jQuery.Unobtrusive.Validation. لمعرفة كيفية استخدامه، استمر في القراءة.

أولاً، في الخلفية، نحدد كلاس ال实体:

/// <summary>
/// معلومات الشركة المصنعة
/// </summary>
public class Manufacturer : OperatedModel
{
  [Key]
  [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  public int ID { get; set; }
  /// <summary>
  /// رمز الائتمان/رقم التسجيل
  /// </summary>
  [مطلوب(ErrorMessage = "رمز الائتمان/رقم التسجيل لا يمكن أن يكون فارغًا)"]
  [MaxLength(30)]
  public string EnterpriseNo { get; set; }
  /// <summary>
  /// اسم الشركة
  /// </summary>
  [مطلوب(ErrorMessage = "اسم الشركة لا يمكن أن يكون فارغًا)"]
  public string EnterpriseName { get; set; }
  /// <summary>
  /// 注册地址
  /// </summary>
  [Required(ErrorMessage = "注册地址不能为空")]
  public string RegisteredAddress { get; set; }
  /// <summary>
  /// 法人
  /// </summary>
  [Required(ErrorMessage = "法人不能为空")]
  public string ArtificialPerson { get; set; }
  /// <summary>
  /// person in charge 负责人
  /// </summary>
  [Required(ErrorMessage = "负责人不能为空")]
  public string PIC { get; set; }
  [Required(ErrorMessage = "手机号不能为空")]
  [RegularExpression(RegexLib.Mobile, ErrorMessage = "手机号码格式不正确")]
  public string Mobile { get; set; }
  [EmailAddress]
  public string Email { get; set; }
  /// <summary>
  /// 商铺号
  /// </summary>
  public string ShopNumber { get; set; }
  /// <summary>
  /// 店铺管理员姓名
  /// </summary>
  public string StoreManagerName { get; set; }
  /// <summary>
  /// 店铺管理员联系方式
  /// </summary>
  [RegularExpression(RegexLib.Mobile, ErrorMessage="手机号码格式不正确")]
  public string StoreManagerNumber { get; set; }
  /// <summary>
  /// 主要执照, 三证合一营业执照
  /// </summary>
  public string MainLicence { get; set; }
  /// <summary>
  /// json, \u5176\u4ed6\u6743\u5361,\u5982\u7f16\u4ea7\u6743\u8bc1
  /// </summary>
  public string OtherLicence { get; set; }
  /// <summary>
  /// \u5165\u9500\u65e5\u671f
  /// </summary>
  [Required(ErrorMessage = "/\u5165\u9500\u65e5\u671f\u4e0d\u80fd\u4e3a\u7a7a")]
  public DateTime EnterDate { get; set; }
  /// <summary>
  /// تاريخ مغادرة العمل
  /// </summary>
  [Required(ErrorMessage = "يجب أن يكون تاريخ الانتهاء غير فارغ")]
  public DateTime QuitDate { get; set; }
  /// <summary>
  /// رأس المال القابل للسحب للشركة
  /// </summary>
  public decimal Balance { get; set; }
}

لدي كل خاصية قواعد التحقق بجهازAttribute، وعند تقديم Model إلى Action الخلفي بواسطة MVC، يقوم الفریمворك بإنجاز عملية التحقق تلقائيًا، لذا يكون المطور الخلفي سعيدًا. ومع ذلك، يجب أن تقوم أيضًا بالتحقق من الجبهة في الجولة الأولى قبل إرسال البيانات، إذا كنت تستخدمjquery.validate، فسيكون عليك كتابة نفس القواعد في js أو العلامات، هل يمكننا تكرار الكود الذي في الخلفية؟ لنأخذ مثالًا على خاصية EnterpriseNo، وكتابة ما يلي في cshtml:

@Html.TextBoxFor(m => m.BasicInfo.EnterpriseNo, new { placeholder = "مطلوب", @class = "form-control" })

الـhtml الناتج النهائي كالتالي:

<input class="form-control" data-val="true" data-val-maxlength="يجب أن يكون طول حقل EnterpriseNo أكبر من 30 حرفًا أو نوعًا من الأعداد أو نوعًا من الأنواع." data-val-maxlength-max="30" data-val-required="يجب أن يكون رمز الشركة أو الرقم المسجل غير فارغ" id="BasicInfo_EnterpriseNo" name="BasicInfo.EnterpriseNo" placeholder="مطلوب" value="" data-original-title="" title="" type="text">

العلامات تضيف تلقائيًا العديد من خصائص تبدأ بـdata-، حيث يُمثلdata-val الحاجة إلى التحقق من هذا التحكم، والخصائص الأخرى التي تبدأ بـdata- هي مجموعة من قواعد التحقق ورسائل الأخطاء عند الفشل، يمكن تخصيص رسائل الأخطاء، وإلا سيقوم الديناميكيات بإنشاء لغة ترجمة آلية مثل "يجب أن يكون طول حقل EnterpriseNo أكبر من 30 حرفًا أو نوعًا من الأعداد أو نوعًا من الأنواع". بالطبع، لا يتعرفjquery.validate على هذه الخصائص، ويجب علىjquery.validate.unobtrusive أن يظهر حتى يعترفjquery.validate.

الآن دعونا نتحدث عن كيفية استخدام هذه js معًا.

الإصدار الجديد من jQuery.validate يدعم نموذج AMD، لذا يمكن استخدامه مباشرة مع requirejs، بينما jQuery.validate.unobtrusive لا يمكنه ذلك، يحتاج إلى تكوين shim، النص الكودي كالتالي:

require.config({
      baseUrl: '/scripts',
      paths: {
        "jquery": 'jquery-2.2.3.min',
        "knockout":'knockout-3.4.0',
        "bootstrap":'../components/bootstrap/3.3.6/js/bootstrap.min','validate':'jquery.validate',
        'validateunobtrusive':'jquery.validate.unobtrusive.min'
      },
      shim : {
        'bootstrap' : {
          deps : [ 'jquery' ],
          exports : 'bootstrap'
        },
        'validateunobtrusive':{
          deps:['validate'],
          exports: 'validateunobtrusive'
        }
      }
    });

بعد من التكوين، في الصفحة ابحث عن require، عند ذلك النقر على زر submit لتقديم النموذج، تبدأ جميع js في العمل. ولكن باستثناء أن التركيز ينحرف إلى أول عنصر فشل التحقق، لا يبدو أن هناك أي تأثير آخر، حتى أن jQuery.validate لا يظهر رسائل الخطأ بشكل افتراضي (وظيفة errorPlacement) لم يعد موجودًا، هل أنت تمزح؟ في الواقع، هذا يرجع إلى أن jQuery.validate.unobtrusive تغطي إعداد errorPlacement (انظر إلى ملف المصدر attachValidation)، بالنسبة لنا، هذا يوفر عملية واحدة. لأن علامات html لـ tooltip هي مولدة ديناميكيًا بواسطة bootstrap، لذا لا يناسب errorPlacement لنا، استنادًا إلى الرابط في بداية المقال، اخترت تعديل وظيفة showErrors، النص الأساسي للكود كما يلي (tooltipvalidator.js):

define(['validateunobtrusive'], function () {}}
  function TooltipValidator() {}
  TooltipValidator.prototype = {
    init: function (validatorOptions, tooltipOptions) {
      tooltipOptions = tooltipOptions || {};
      validatorOptions = validatorOptions || {};
      this._tooltipOptions = $.extend({}, {
        placement: 'top'
      }, tooltipOptions, { animation: false });
      this._validatorOptions = $.extend({}, {
        //errorPlacement: function (error, element) {
        //  // do nothing
        //},
        showErrors: function (errorMap, errorList) {
          for (var i = 0; i < this.successList.length; i++) {
            var success = this.successList[i];
            $(this.successList[i]).tooltip('destroy');
            $(this.successList[i]).parents('div.form-group').removeClass('has-error');
          }
          for (var i = 0; i < errorList.length; i++) {
            var errorElement = $(errorList[i].element);
            errorElement.parents('div.form-group').addClass('has-error');
            errorElement.attr('data-original-title', errorList[i].message).tooltip('show');
          }
        },
        submitHandler: function (form) {
          return false;
        }
      }, validatorOptions)
      this._configTooltip();
      this._configValidator();
    },
    _configTooltip: function () {
      $('[data-val="true"]').tooltip(this._tooltipOptions);
    },
    _configValidator: function () {
      $.validator.setDefaults(this._validatorOptions);
      $.validator.unobtrusive.parse(document);
    }
  }
  return new TooltipValidator();
});

بالتالي يمكننا تنفيذ tooltipvalidator.init في دالة التلقي لـ require دون الحاجة إلى كتابة منطق إضافي، مما يجعل الطلاب المتخصصين في الجانب الأمامي من النظام يحصلون على فرحهم. هناك ملاحظة يجب الانتباه لها هنا، حيث يمكنكم رؤية سطر الرقم 49 من الكود، وهو خطوة التدريب لـ jquery.validate.unobtrusive. كان jquery.validate.unobtrusive يحتوي بالفعل على $(function () { $jQval.unobtrusive.parse(document); }); ولكن $.ready يتم تنفيذه عند اكتمال تحميل عناصر DOM (ملاحظة جانبية: ليس عند اكتمال التطبيق) مما يؤدي إلى تنفيذه قبل أن يكون tooltipvalidator قد أتم _configValidator، مما يجعل إعداداتنا غير نافذة (إذا كنتم تستخدمون تطبيق صفحة واحدة بدون تحديث، ستلاحظون أن الإعدادات تصبح نافذة عند تحميل المكونات المحلية مرة أخرى، لأن $.ready يتم تنفيذه فقط عند التحميل الأول، بينما يتم تنفيذ دالة التلقي لـ require في كل تحميل). هناك طريقتان لحل هذه المشكلة: 1- جعل jquery.validate.unobtrusive يعتمد على tooltipvalidator؛ 2- إزالة $jQval.unobtrusive.parse(document) من jquery.validate.unobtrusive. اخترت الطريقة الثانية.

شكرًا على القراءة، نأمل أن يساعدكم هذا، شكرًا لدعمكم لموقعنا!

بيان: محتوى هذا المقال تم جمعه من الإنترنت، ويحق لصاحب الحقوق أن يتحكم فيه، ويتم جمع المحتوى بشكل تلقائي من قبل مستخدمي الإنترنت، ويستخدم هذا الموقع ليس لديه حقوق الملكية، ولا يتم تعديل المحتوى بشكل يدوي، ولا يتحمل هذا الموقع أي مسؤولية قانونية. إذا كنت قد وجدت محتوى مخالف لحقوق النسخ، فنرجو منك إرسال بريد إلكتروني إلى: notice#oldtoolbag.com (يرجى استبدال # ب @ عند إرسال البريد الإلكتروني) لتقديم الشكوى، وقدم الأدلة ذات الصلة، وإذا تم التحقق من ذلك، سيتم حذف المحتوى المزعوم فوراً.

توصيات لك