Handlebars.js: المقاود لا تعمل في الجداول

تم إنشاؤها على ١٥ أغسطس ٢٠١٣  ·  37تعليقات  ·  مصدر: handlebars-lang/handlebars.js

http://jsfiddle.net/cwYhN/3/

لاحظ أن نفس المقاود # كل ينجح عندما تكون خارج الجداول. يشتمل jsfiddle الخاص بي على ناتجين محددين يوضحان ذلك.

التعليق الأكثر فائدة

أعلم أن هذه المشكلة قديمة جدًا ، لكنني واجهت هذا مؤخرًا بسبب عدم اتباع محرر قالب البريد الإلكتروني الخاص بـ Sendgrid لأفضل الممارسات هذه. إذا انتهى الأمر بأي شخص آخر بشأن هذه المشكلة من Google لهذا السبب ، فإن الحل البديل هو وضع كود المقاود في تعليق HTML.

<table >
  <tbody>
    <!-- {{#each items}} -->
    <tr>
      <td>{{this.key}}</td>
      <td>{{this.value}}</td>
    </tr>
    <!-- {{/each}} -->
  </tbody>
</table>

التي تنتج الناتج التالي

<table>
  <tbody>
    <!--  -->
    <tr>
      <td>my key</td>
      <td>my value</td>
    </tr>
    <!--  -->
    <!--  -->
    <tr>
      <td>my key 2</td>
      <td>my value 2</td>
    </tr>
    <!--  -->
  </tbody>
<table>

(ملاحظة: لم أتحقق من ذلك باستخدام المقاود مباشرة ، فقط في محرر قالب Sendgrid)

ال 37 كومينتر

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

http://jsfiddle.net/cwYhN/6/

يبدو أن هذا قد يكون مشكلة في jQuery أو أي شيء آخر ... عندما تفعل console.log(frag); ستلاحظ أن المساعد {{#each}} تم دفعه خارج الجدول حتى قبل محاولة تجميعه باستخدام المقاود ...

لقد قمت بتحديث jsfiddle لوضع القالب داخل علامة <script type="text/x-handlebars-template"></script> ويبدو أنه يعمل بشكل جيد ...

http://jsfiddle.net/doowb/6GdPy/1/

نعم ، لقد اكتشفت للتو ما يلي:
http://jsfiddle.net/cwYhN/10/

لما يستحق الأمر ، أعتقد أنه يتجاهل المتصفح ما يعتبره html غير صالح ، بدلاً من عيب jquery.

نعم ، لم أكن متأكدًا مما إذا كانت ستكون أشياء jQuery أو وظيفة المتصفح الأصلية التي يستدعيها jQuery. في كلتا الحالتين ، لا يعجبه {{ }} بين tbody و tr .

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

<table>
  <tbody handlebars="{{each}}">
    ... these get iterated ...
  </tbody>
</table>

إن السماح بشيء من هذا القبيل سيمنع المتصفح من تجريد كل عبارة مهمة ، ويمكن أن تظهر على علامة الإغلاق التي تنتمي إليها (/ tbody)

كما أشرت يا رفاق بالفعل ، فإن المحلل اللغوي HTML مرتبك من خلال ترميز المقاود ويأتي بهذا باعتباره بنية DOM التي تحاول تحويلها إلى قالب المقاود:

            {{#each activity}}

            {{/each}}
        <table style="border:1px solid #ccc;">
        <thead>
            <tr><th>Month</th>
            <th>Imps</th>
            <th>Clicks</th>
            <th>Spend</th>
        </tr></thead>
        <tbody><tr>
                <th>{{month}}</th>
                <td>{{impressions}}</td><td>{{clicks}}</td><td>{{spend}}</td>
            </tr></tbody>
    </table>

يجب استخدام شيء مثل سلوك البرنامج النصي أعلاه ، أو سلاسل جافا سكريبت ، أو التجميع المسبق للتغلب على هذا.

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

أهدرت للتو نصف يوم قبل اكتشاف أن {{#each}} لا يعمل في الجداول. سيكون من المفيد حقًا إذا تم ذكر ذلك ببساطة في الوثائق.

كل منها يعمل بشكل جيد في الجداول إذا تم تحميله بشكل صحيح. كيف حالك تحميل القوالب الخاصة بك؟

preichelt يجب تحميل المقاود من داخل علامات البرنامج النصي لمنع المتصفح من العبث {{#each}} في الجداول. يمكنك قراءة المزيد عن تجاوز سعة المكدس:

http://stackoverflow.com/questions/15386276/why-should-we-wrap-our-templates-inside-script-blocks

لقد أهدر هذا الخطأ ساعتين من حياتي والآن الساعة 10:30 مساءً يوم السبت ، أعمل في مكتبي فقط لحل هذا الخطأ حتى اكتشفت هذه المشكلة و [Official Block Doc]
(http://handlebarsjs.com/builtin_helpers.html) لا يقول شيئًا عن ذلك.

في حال لم يكن واضحا، وهذا ليس خطأ من المقاود، ولكن لك لعدم معرفة كيفية عمل HTML: https://html.spec.whatwg.org/multipage/syntax.html#an -introduction إلى الخطأ التعامل مع الحالات الغريبة في المحلل اللغوي

لذا ، أنت تفترض أن كل شخص يحاول استخدام Handlebarsjs يجب أن يكون لديه فهم جيد لكيفية عمل محلل HTML؟ وإذا لم يكن كذلك ، فهل الخطأ هو خطأ المستخدم وليس خطأ وضوح الوثائق؟ هذا الافتراض لا معنى له. محرك قالب آخر ثقيل ومعقد ، Angularjs ، يستخدم بناء جملة متوافق مع Html كتركيب القالب الخاص بهم ، على سبيل المثال ، إذا كنت بحاجة إلى تكرار الجدول ، فيمكنني استخدام

<tr ng-repeat="dto in tableData">

وتحافظ Angularjs على الحالة الداخلية للحلقة باستخدام تعليقات Html:

<!-- ngRepeat: column in row -->
<tr ng-repeat="dto in tableData">

يحاول Angualrjs احترام واتباع بناء جملة Html قدر الإمكان وتجنب الافتراض بنجاح. لكن بناء جملة نموذج Handlebarsjs لا يعرض مشكلة المحلل اللغوي لـ Html للمستخدمين.
إذا لم يتمكن المطور من حل المشكلة إلى جانبك ، ثم لديك _duty_ لإخبار المستخدمين لديك بأن يكونوا على دراية بالمشكلة إذا كنت تهتم حقًا بمشروعك ومستخدميك من جميع أنحاء العالم.
على أي حال ، سأقوم بفتح إصدار مستند لأنني أعتقد أنني لست أول من واجه مشكلة الصداع هذه ولن أكون الأخير. _

يعمل Angular في DOM ، لذا فهو مدرك لـ DOM. تعمل المقاود مع السلاسل فقط وليس لها مفهوم عن DOM.

profullstack : كما قال stevenvachon ، لا تعمل المقاود مع HTML ، ولكن مع النص فقط. لكن هذا قد لا يكون واضحًا من المستندات ، لأن جميع الأمثلة هي HTML. يستخدمه شخصيًا أيضًا لإنشاء تخفيض السعر ...

إذا أمكنك إخباري ، ما هو نوع النص الذي قد تحتاجه في المستندات ، فسأكون سعيدًا لإضافته. ومع ذلك ، فإن إرشادات الاستخدام العامة (بما في ذلك الجزء الذي يحتوي على العلامة <script> موجودة بالفعل على الصفحة الرئيسية من http://handlebarsjs.com/. لهذا السبب لست متأكدًا مما تحتاجه هنا.

profullstack أشعر بالإحباط بسبب "إضاعة الوقت" ، لكن في رأيي ، لقد حصلت على هذا بشكل عكسي تمامًا.

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

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

ErisDS شكرا لك على نصيحتك. ربما كان تعليقي الأول قويًا جدًا ، لكنني أتفق تمامًا مع رأيك حول:

to try to making other developers lives easier

ولماذا أسقط Angularjs لاستخدام Handlebarsjs؟ _لأنني أعتقد أن Handlebarsjs ستجعل حياتي أسهل من Angularjs._
لذا ، ما عليك سوى إضافة بعض كلمات الإشعار في الوثائق لمساعدة الآلاف من مستخدمي المصادر المفتوحة لديك لتجنب المشكلة المحتملة ضد إرادتك المتمثلة في "تسهيل حياة المطورين الآخرين"؟ أعتقد أنه لا.
ل:

No open source project nor contributor has any duty to you.

نعم هذا صحيح. يمكنك بدء مشروع مفتوح المصدر ثم إسقاطه ، فلا بأس بذلك. ولكن عندما ينمو مشروعك ، فإنك تقضي المزيد من الوقت والقلب في مشروعك ، فأنت تحب أكثر بمشروعك وتريد أيضًا مشاركته مع العالم. في هذا الوقت ، ستبدأ في _الاهتمام بمستخدميك_ و _ الاهتمام بوثائقك_. إن Handlebarsjs في هذه المرحلة ، هذا ليس مشروعًا صغيرًا ، إنه مشروع مشهور ويستخدمه المبرمجون في جميع أنحاء العالم ، حتى في كوريا الجنوبية ، في الصين وما إلى ذلك.
على حد علمي ، يفخر معظم مبرمجي المصدر المفتوح على Github بمشروعهم وملفهم README.md ، ويتمنون أن يستخدم المزيد والمزيد من الأشخاص أدواتهم ورموزهم.
حتى إذا:

  • لا تريد أن تهتم بمستخدمي المصادر المفتوحة
  • أنا آخر من سيواجه هذه المشكلة
    يمكنك تجاهل تحليلي الفني تمامًا في التعليق الأول والمناقشة التي تفضلها المستخدم في هذا التعليق.
    علاوة على ذلك ، فإن المشروع مفتوح المصدر ليس شيئًا مثل "الصدقة" التي تقدمها للعالم ، إنه _جسر الاتصال_ بينك وبين المبرمجين الآخرين.

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

{{#each myListData}}
                        <tr>{{name}}</tr>
{{/each}}

إذا كان مجرد استبدال ، أتوقع شيئًا كهذا:

<tr>nameA</tr>
<tr>nameB</tr>

ولكن عندما تصادف HTML ، فإنها تتصرف بشيء مختلف ، وذلك بسبب stevenvachon .
لذلك أعتقد أن جملة واحدة فقط ستكون كافية أسفل قسم "مساعد كل مجموعة":

WARNING: please use script block when you try to use #each block inside table, due to the know issue of [How HTML parse works(thanks for <strong i="18">@stevenvachon</strong>'s reference](https://html.spec.whatwg.org/multipage/syntax.html#an-introduction-to-error-handling-and-strange-cases-in-the-parser)

أنا أقدر ذلك حقًا إذا كنت ستشارك برأيك. شكرا.

الشيء هو أن هذا لا علاقة له بالمساعد #each . يجب ألا تكتب

ربما يمكننا تقديم تحذير مثل تحذيرك أدناه المثال الموجود في الصفحة المقصودة ...

مجرد ملاحظة أخرى:

لن أستخدم طريقة الكتل النصية في الإنتاج. بدلاً من ذلك ، سأستخدم Webpack أو أداة أخرى لترجمة القوالب مسبقًا.

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

You **can** deliver a template to the browser by including it in a <script> tag.

إلى

You **should always** deliver a template to the browser by including it in a <script> tag.

أعتقد اقتراحك:

**never** write a template directly into HTML

صحيح تمامًا ، ويجب وضعه في الصفحة المقصودة للسماح للجميع بمتابعة ذلك ويمكنه تجنب العديد من المشكلات. أعتقد أنها فكرة جيدة ، هل تعتقد ذلك؟

ومع ذلك ، فإن هذا التفسير لا يعمل ، لأنهم قد يفهمونه على أنه:

<script type="text/x-handlebars">
  {{#each list as |item|}}
    <td>{{item}}</td>
  {{/each}}
</script>

stevenvachon نعم ، مجرد وضع القوالب داخل البرنامج النصي ليس كافيًا في

ربما:

بالنسبة لمعظم تطبيقات الإنتاج ، لن ترغب في استخدام المحلل اللغوي وقوالب السلسلة. ابحث في التجميع المسبق.

stevenvachon شكرًا على تعليقاتك وأعتقد أنه سيكون من الأفضل وضع رابط محلل HTML مع تعليقاتك:

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

ربما ينبغي تقسيمها إلى

  1. أسفل مثال العلامة <script> مباشرةً

من المهم أن تضع القالب داخل علامة <script> . لا تضعه في HTML مباشرة وإلا فقد يقوم المحلل اللغوي بتعديله (على سبيل المثال ، إذا كان يحتوي على جدول )

  1. قم بتغيير النقطة النقطية حول التجميع المسبق إلى.

يرجى ملاحظة أن هذا الأسلوب غير موصى به لتطبيقات الإنتاج. من الممكن أيضًا تجميع القوالب مسبقًا. [...]

في الواقع ، أنا شخصياً لن أستخدم Handlebars في المتصفح بعد الآن: هناك العديد من الأطر الأخرى (ليس فقط Angular و React ، ولكن أيضًا Vue و Ractive). هذا الفيديو رائع جدًا ويظهر المشكلة ...

أستخدم المقاود على الخادم وكمولد للصفحة الثابتة ، ولكن بالنسبة لعرض المتصفح ، أعتقد أن هناك طرقًا أفضل.

nknapp بدأت في كتابة مُحلل المقاول- html-parser لاستخدامه في إحضاره إلى المتصفح من خلال VDOMs ، لكنه واجه مقاومة .

nknapp شكرا

  1. أهمية وضع القالب داخل ملف

profullstack لست

لقد أجريت التغييرات.

nknapp شكرًا لك ، أعتقد أن الكثير من الأشخاص سيستفيدون من تغييراتك.

أعلم أن هذه المشكلة قديمة جدًا ، لكنني واجهت هذا مؤخرًا بسبب عدم اتباع محرر قالب البريد الإلكتروني الخاص بـ Sendgrid لأفضل الممارسات هذه. إذا انتهى الأمر بأي شخص آخر بشأن هذه المشكلة من Google لهذا السبب ، فإن الحل البديل هو وضع كود المقاود في تعليق HTML.

<table >
  <tbody>
    <!-- {{#each items}} -->
    <tr>
      <td>{{this.key}}</td>
      <td>{{this.value}}</td>
    </tr>
    <!-- {{/each}} -->
  </tbody>
</table>

التي تنتج الناتج التالي

<table>
  <tbody>
    <!--  -->
    <tr>
      <td>my key</td>
      <td>my value</td>
    </tr>
    <!--  -->
    <!--  -->
    <tr>
      <td>my key 2</td>
      <td>my value 2</td>
    </tr>
    <!--  -->
  </tbody>
<table>

(ملاحظة: لم أتحقق من ذلك باستخدام المقاود مباشرة ، فقط في محرر قالب Sendgrid)

شكرا لهذه النصيحة gurpreetatwal . لقد وفرت لي ساعات من تصحيح الأخطاء هذا المساء مع هذا الشهي لـ SendGrid!

gurpreetatwal ولكن لماذا؟

Lazarencjusz لماذا فيما يتعلق لماذا يعمل الإصلاح أو لماذا لا يعمل محرر قالب البريد الإلكتروني SendGrid بشكل صحيح؟

أهلا! عند استخدام عناصر div بدلاً من الجدول ، فسيتم العمل.
أعد أيضًا كتابة جميع عناصر الجدول إلى div.

يعمل حل gurpreetatwal بالنسبة لي على قوالب Mailchimp / Mandrills للمقاود. شكرا لانقاذ لي الكثير من المتاعب!

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات