Handlebars.js: هل تدعم الخرائط والمجموعات والمتكررات المخصصة في مساعد "كل" مساعد؟

تم إنشاؤها على ١٠ يناير ٢٠١٨  ·  6تعليقات  ·  مصدر: handlebars-lang/handlebars.js

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

هل هناك خطة أو رغبة في تقديم الدعم لهذه الأنواع من القوائم في المساعد المدمج each ؟ أسأل لأنني أفهم أن Handlebars تهدف إلى تجنب polyfills وأتصور أن الطريقة الوحيدة لجعل المساعد الجديد يعمل دون المساومة على دعم المتصفح هو تمكين الدعم تدريجيًا لأنواع القوائم المختلفة التي تعتمد على البيئة الأصلية أو دعم polyfilled مسبقًا مقابل Set و Map و Symbol .

Handlebars.registerHelper("each", function (contexts, options) {

    // Throw a runtime exception if options were not supplied.
    if (!options) {
        throw new Handlebars.Exception("Must pass iterator to #each");
    }

    // If the "list of contexts" is a function, execute it to get the actual list of contexts.
    if (typeof contexts === "function") {
        contexts = contexts.call(this);
    }

    // If data was supplied, frame it.
    const data = options.data ? Object.assign({}, options.data, { _parent: options.data }) : undefined;

    // Create the string into which the contexts will be handled and returned.
    let string = "";

    // Create a flag indicating whether or not string building has begun.
    let stringExtensionStarted = false;

    // Create a variable to hold the context to use during the next string extension. This is done to
    // allow iteration through the supplied list of contexts one step out of sync as they are looped
    // through later in this helper, ensuring a predictable sequence of value retrieval, string
    // extension, value retrieval, string extension...
    let nextContext;

    // Create a function responsible for expanding the string.
    const extendString = (final = false) => {

        // If other contexts have been encountered...
        if (nextContext) {

            // Expand the string using the block function.
            string += options.fn(nextContext.value, {
                data: data ? Object.assign(data, {
                    index: nextContext.index,
                    key: nextContext.key,
                    first: !stringExtensionStarted,
                    last: final
                }) : undefined,
                blockParams: [nextContext.key, nextContext.value]
            });

            // Note that string extension has begun.
            stringExtensionStarted = true;

        // If no contexts have been encountered and this is the final extension...
        } else if (final) {

            // Expand the string using the "else" block function.
            string += options.inverse(this);

        }

    };

    // If a list of contexts was supplied...
    if (contexts !== null && typeof contexts !== "undefined") {

        // Start a counter.
        let index = 0;

        // If an array list was supplied...
        if (Array.isArray(contexts)) {

            // For each of the possible indexes in the supplied array...
            for (const len = contexts.length; index < len; index++) {

                // If the index is in the supplied array...
                if (index in contexts) {

                    // Call the string extension function.
                    extendString();

                    // Define the context to use during the next string extension.
                    nextContext = {
                        index: index,
                        key: index,
                        value: contexts[index]
                    };

                }

            }

        // If a map list was supplied...
        } else if (contexts instanceof Map) {

            // For each entry in the supplied map...
            for (const [key, value] of contexts) {

                // Call the string extension function.
                extendString();

                // Define the context to use during the next string extension.
                nextContext = {
                    index: index,
                    key: key,
                    value: value
                };

                // Increment the counter.
                index++;

            }

        // If an iterable list was supplied (including set lists)...
        } else if (typeof contexts[Symbol.iterator] === "function") {

            // Get an iterator from the iterable.
            const iterator = contexts[Symbol.iterator]();

            // Create a variable to hold the iterator's next return.
            let next;

            // Do the following...
            do {

                // Iterate and update the variable.
                next = iterator.next();

                // If there is anything left to iterate...
                if (!next.done) {

                    // Call the string extension function.
                    extendString();

                    // Define the context to use during the next string extension.
                    nextContext = {
                        index: index,
                        key: index,
                        value: next.value
                    };

                    // Increment the counter.
                    index++;

                }

            // ... until there is nothing left to iterate.
            } while (!next.done);

        // If a list other than an array, map, or iterable was supplied...
        } else {

            // For each key in the supplied object...
            for (const key of Object.keys(contexts)) {

                // Call the string extension function.
                extendString();

                // Define the context to use during the next string extension.
                nextContext = {
                    index: index,
                    key: key,
                    value: contexts[key]
                };

                // Increment the counter.
                index++;

            }

        }

    }

    // Call the string extension a final time now that the last supplied context has been encountered.
    extendString(true);

    // Return the fully-extended string.
    return string;

});

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

karlvr هل يمكنك بدء إصدار جديد لدعم الخريطة. تم بالفعل حل أجزاء من هذه المشكلة وأود أن أحصل على بداية نظيفة.

ال 6 كومينتر

يجب أن يكون ممكنًا الآن مع # 1557

nknapp يبدو أن التنفيذ في # 1557 لا يدعم Map بشكل صحيح. ينتج حاليًا عنصرًا متكررًا وهو المدخل_ في Map ، وهو مجموعة من [key, value] ، في حين أن مثال الكود أعلاه يجعل العنصر المتكرر value ويعين @key ، وأنا أظن أنه الأفضل. إنه أفضل لي!

أيضًا ، يبدو أن التعبيرات لا تدعم حاليًا Map ، لذلك لا يمكنك قول {{person.myMap.myMapKey}} . أنا أتعمق أكثر في هذه القضية الآن.

مع إضافة lookupProperty في runtime.js يمكننا البحث عن الخصائص في Map s:

    lookupProperty: function(parent, propertyName) {
      if (parent instanceof Map) {
        return parent.get(propertyName)
      }

هل هناك أي شهية لإضافة دعم مثل هذا؟

@ karlvr أعتقد أن اقتراحك يستحق النظر فيه. لكني أود مناقشته.

karlvr هل يمكنك بدء إصدار جديد لدعم الخريطة. تم بالفعل حل أجزاء من هذه المشكلة وأود أن أحصل على بداية نظيفة.

nknapp شكرا جزيلا لردك السريع ؛ لقد أجريت للتو علاقات عامة مع التغييرات المقترحة. هل يمكن أن نناقش هناك؟ # 1679

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