إنتقل إلى المحتوى الرئيسي

كتابة قاعدة عمل

الهدف​

اجعل النموذج يستجيب لما يفعله من يملؤه: أظهر حقل المدير فقط للمصروفات التي تتجاوز ١٠٠، عطّل تاريخ الإغلاق حتى تُربح الصفقة، واملأ العملة من الحساب.

المتطلبات​

  • أنت مسجَّل الدخول بصفة صانع، وحل الجدول مفتوح.
  • الجدول يحتوي الحقول التي تتحدث عنها القاعدة، وإذا أردت ربط القاعدة بنموذج واحد فذلك النموذج موجود.

ما هي قاعدة العمل وما ليست​

تعمل قاعدة العمل في المتصفح، على النموذج، وتغيّر سلوك النموذج. لها أربعة أفعال: إظهار حقل أو إخفاؤه، تفعيله أو تعطيله، جعله مطلوباً أو لا، وتعيين قيمة.

وهي لا تقرّر ما يمكن حفظه. يستطيع أحدهم تعطيل القاعدة، أو استخدام شاشة أخرى، أو استدعاء الواجهة البرمجية مباشرة، ويُحفظ السجل رغم ذلك. كل ما يجب أن يكون صحيحاً في البيانات مكانه خطوة إضافة على الخادم، وهي تعمل مهما فعل المتصفح. استخدم قاعدة العمل لتجعل النموذج مريحاً، وخطوة الخادم لتجعل القاعدة حقيقية. من الطبيعي أن تريد الاثنتين، وهما تُكتبان منفصلتين عن قصد.

الخطوات​

  1. افتح النموذج الذي تخصّه القاعدة — الجدول، ثم النماذج، ثم النموذج — واختر الأحداث من شريط أدواته. تعرض القائمة كل قاعدة تعمل على هذا النموذج، بما فيها المرتبطة بـكل نماذج الجدول.

  2. اختر جديد، فيُفتح مصمم القاعدة.

  3. اكتب اسم العرض. يُملأ الاسم المنطقي تلقائياً مسبوقاً ببادئة ناشرك، ويثبت بعد الحفظ.

  4. تحقّق من النموذج. هو أصلاً النموذج الذي جئت منه، وهذا صحيح في الغالب — فالقاعدة تتحدث عن حقول، والحقول التي تتحدث عنها هي التي أمامك. حوّله إلى كل النماذج لشيء ينبغي أن يصحّ أينما ظهر الجدول، مثل «أخفِ هذا ما لم تكن الحالة معتمدة». والقاعدة المرتبطة بكل النماذج تظهر مع ذلك في قائمة أحداث كل نموذج، موسومة بذلك.

  5. اختر متى تعمل — حدث واحد لكل قاعدة:

    • عند فتح النموذج يطبّق القاعدة مع عرض السجل.
    • عند تغيّر حقل يُظهر منتقي الحقول. اختر حقلاً فيظهر كشارة؛ أضف ما تحتاجه القاعدة، واحذف واحدة بعلامة ✕ على شارتها.
    • عند حفظ النموذج يشغّل القاعدة بين الضغط والكتابة، فتستطيع ملء قيمة — أو إيقاف الحفظ بـ cancelSave أدناه.

    القاعدة بلا مُشغّل لا تعمل أبداً، لذا يبقى زر حفظ معطّلاً حتى تحصل قاعدة تغيّر الحقل على حقل واحد على الأقل.

    الحدث الواحد لكل قاعدة مقصود. وحين يجب أن يحدث الشيء نفسه في لحظتين — وهي الحالة الشائعة، مثل «أظهر هذا حين تكون الحالة مرفوضة»، وهو ما يجب أن يصحّ عند فتح النموذج وكلما تغيّرت الحالة — اكتب قاعدتين تستوردان نصًّا برمجيًّا للحل واحدًا، كل واحدة من سطرين. يُكتب المنطق مرة واحدة؛ وحيث تختلف اللحظتان فعلًا، يسأل النص نفسه eventType() ويقرّر. أما عدة مُشغّلات على قاعدة واحدة فلا تضع ذلك القرار في أي مكان: لا شيء على الشاشة يقول أيّ نصف من النص يخصّ أيّ حدث.

  6. اكتب النص البرمجي في المحرر. يضع خطاً تحت الأخطاء أثناء الكتابة، ويكمل دوال المنصة، ويعرض وسائط كل دالة عند فتح القوس. وزر العين في أعلى زاوية المحرر يفتح ما يمكن للنص استدعاؤه فوق الكود.

  7. اترك مُفعّلة محددة، أو أزل التحديد للاحتفاظ بالقاعدة دون تشغيلها.

  8. اختر حفظ.

ما يمكن للنص استدعاؤه​

الاستدعاءما يفعله
getValue(field)القيمة الحالية للحقل على النموذج.
setValue(field, value)يعيّن قيمة حقل.
setVisible(field, visible)يُظهر حقلاً أو يخفيه.
setDisabled(field, disabled)يجعل الحقل للقراءة فقط أو لا.
setRequired(field, required)يجعل الحقل مطلوباً أو لا.
eventType()"OnLoad" أو "OnChange" أو "OnSave" — الحدث الجاري.
changedField()الحقل الذي أطلق OnChange، وإلا "".
isNewRecord()true ما دام السجل لم يُحفظ بعد. استخدمه لقفل حقل يُختار مرة واحدة ثم يبقى، مثل نوع النشاط.
cancelSave(message)عند الحفظ فقط: يوقف حفظ هذا النموذج ويعرض الرسالة.
isEmpty(value)هل القيمة غير مملوءة. النص الفارغ و«لا شيء» فارغان؛ أما 0 وfalse فقيمتان اختارهما أحدهم.

يُسمّى الحقل باسمه المنطقي (par_amount) لا باسم العرض.

والحقل الذي لا شيء فيه يُقرأ نصًّا فارغًا، لذا فإن getValue("par_currency") == "" هو فحص «لم يُملأ بعد» — وهكذا يعمل مثال العملة أدناه. أما الرقم والتاريخ والبحث فلا نص فارغ يُقارن به، فاسأل هناك isEmpty(getValue("par_due")). وهي تستخدم تعريف «الفارغ» نفسه الذي يستخدمه فحص الحقول المطلوبة في النموذج، ولهذا لا تستطيع قاعدة أن تملأ حقلًا قبِله النموذج للتوّ مملوءًا.

getValue وsetValue مكتوبتان وتعملان تماماً كما في خطوة الخادم، حتى يقرأ المنطق الذي تضعه مرة واحدة بالطريقة نفسها على الجانبين.

يُقرأ الحقل الرقمي رقماً — 1200.5 لا "1200.5" — حتى أثناء الكتابة، ويظل الحقل غير المملوء فارغاً. ويهمّ ذلك لحظة أن تكتب دالة خاصة بك: فـfunc needsApproval(amount: number) لا تقبل نصّاً، والخطأ هو Function overload for needsApproval not found. لا شيء عن الأنواع. لذا صرّح عن المبلغ بأنه number لا int — فعمود Decimal يحمل 1200.50 ويرفضه بارامتر العدد الصحيح — وضَع صفراً مكان الصندوق الفارغ قبل أي عملية حسابية:

func claimAmount(): number {
var raw = getValue("par_amount");
if (isEmpty(raw)) { return 0; }
return raw;
}

…وكل ما يصدّره نص برمجي للحل. حين تبدأ الأسطر نفسها بالظهور في عدة قواعد، انقلها إلى نص برمجي للحل واستورده بكتابة import 'par_expense_helpers'; في أعلى القاعدة — يكمل المحرّر الاسم، ويعرف بعدها ما يصدّره ذلك النص.

الخيارات، وإظهار قسم لأحدها​

يُقرأ الخيار على أنه رقمه، أي القيمة التي أُعطيت للخيار (110000001)، سواء فُتح النموذج للتو أو اختاره أحدهم للتو. لذا قارنه برقم، لا بنص:

if (getValue("pw_type") == 110000001) { setVisible("pw_to", true); }

قبل ذلك كان الخيار الذي اختاره أحدهم للتو يُقرأ نصًا ("110000001")، فتتوقف المقارنة أعلاه عن العمل بصمت بعد أول اختيار. القاعدة التي كانت تقارن بنص بين علامتي اقتباس يجب أن تُزال منها العلامتان.

لإظهار قسم لخيار واحد فقط، أخفِ الحقول التي فيه. القسم الذي أُخفيت كل حقوله يختفي بعنوانه، ويعود حين تُظهر قاعدة أحدها من جديد. هكذا يُظهر نموذج النشاط في مبيعات بارسوير قسم «البريد الإلكتروني» للبريد وقسم «مكالمة هاتفية» للمكالمة.

لجعل حقل يُختار مرة واحدة، عطّله حين لا يكون السجل جديدًا:

setDisabled("pw_type", !isNewRecord());

حين يُحفظ سجل جديد، تعمل القواعد التي تعمل عند الفتح مرة أخرى، فيُقفل الحقل فورًا. وكأي قاعدة، هذا يوقف النموذج فقط. ليُمنع API أو الاستيراد من تغيير الحقل أيضًا، اكتب خطوة إضافة على الخادم كذلك.

إيقاف الحفظ​

القاعدة التي تعمل عند حفظ النموذج تستطيع رفض الحفظ:

if (getValue("par_status") == "rejected" && getValue("par_reason") == "") {
cancelSave("اذكر سبباً قبل رفض هذه المطالبة.");
}

يتوقف الحفظ، وتظهر رسالتك أعلى النموذج، ولا يضيع شيء — يبقى النموذج مفتوحاً بكل ما كُتب فيه.

وهذا ليس إلزاماً بعد: إنه يوقف هذا النموذج، في هذا المتصفح. أما الـ API والاستيراد والتطبيق المخصص وأي نموذج آخر بلا هذه القاعدة فتحفظ السجل كما هي. وُجد لأن جملة «لا تدعني أرسل هذا ناقصاً» تستحق أن تُقال على النموذج — لكن إن وجب أن يكون الأمر صحيحاً في البيانات، فاكتب خطوة إضافة على الخادم أيضاً.

مثال​

أظهر حقل المدير واجعله مطلوباً فقط للمصروفات فوق ١٠٠ — عند الفتح وكلما تغيّر المبلغ:

var over = getValue("par_amount") > 100;
setVisible("par_manager", over);
setRequired("par_manager", over);

لاحظ أنه يقول ما ينبغي أن يكون صحيحاً في الاتجاهين. القاعدة التي تُظهر الحقل فقط ستتركه على الشاشة بعد أن ينخفض المبلغ، لأن لا أحد طلب إخفاءه ثانية.

قاعدتان على نموذج واحد​

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

لا قاعدة تعمل إلى الأبد​

لكل قاعدة ميزانية، والقاعدة التي تتجاوزها تُوقَف ويُبلَّغ عنها باسمها. وهناك ثلاثة حدود، يمسك كلٌّ منها خطأً مختلفًا:

يوقفمتى
حلقة لا تنتهيwhile (true)، أو شرط لا يتحقّق أبدًا تمامًا
قاعدة تعمل ببساطة أكثر مما ينبغيما زالت تعمل بعد نصف ثانية
دالة تستدعي نفسها بلا نهايةبلغت مئة استدعاء دون أفق للانتهاء

يظل النموذج يعمل، ويبقى ما كتبه الشخص، وتذكر الرسالة اسم القاعدة ورقم السطر. ولا يفيد لفّ الحلقة في try — فالميزانية ليست شيئًا يستطيع النص التقاطه.

ولن تصادف هذا مصادفةً: أكبر قاعدة في الأمثلة تستهلك أقل من واحد بالمئة من المسموح. وإن صادفته فالقاعدة بها خلل — غالبًا while لا يغيّر جسدُها شرطَها.

وملاحظة عن مقارنة القيم. يقارن == داخل النوع الواحد: رقمان، أو نصّان، أو قيمتا صواب/خطأ. والنوعان المختلفان لا يتساويان أبدًا — 1 == "1" خطأ — و«لا شيء» يساوي «لا شيء»، فالحقل غير المملوء لا يساوي "". ولهذا يُقرأ الحقل الذي لا قيمة له نصًّا فارغًا، ولهذا وُجدت isEmpty() للأرقام والتواريخ.

استكشاف الأخطاء​

  • قاعدة لا تعمل أبداً فيما يبدو. تحقق أنها مُفعّلة، وأن ارتباطها بالنموذج يطابق النموذج الذي تنظر إليه، وأن مُشغّلها يشمل الحقل الذي تغيّره.
  • «BS Lang script is invalid: …» عند الحفظ — النص لا يُحلَّل. المحرر يضع خطاً تحت الخطأ نفسه، والرسالة تذكر السطر.
  • «Form '…' was not found on '…'.» — القاعدة مرتبطة بنموذج لا يملكه الجدول. اختر واحداً من القائمة أو اربطها بكل النماذج.
  • رسالة حمراء أعلى نموذج في التطبيق تذكر اسم قاعدة. أخفقت القاعدة أثناء التشغيل. يستمر النموذج في العمل، وتتوقف القاعدة عند موضع الإخفاق.
  • خطوط تحت getValue — لم يعد المحرر يعتبر دوال المنصة نفسها غير معرّفة. إن رأيت ذلك فالنص يستدعي شيئاً ليس في القائمة أعلاه.

سيناريوهات ذات صلة​