Handlebars.js: λ‚΄μž₯된 "각각" λ„μš°λ―Έμ—μ„œ 지도, μ„ΈνŠΈ 및 μ‚¬μš©μž μ •μ˜ 반볡 κ°€λŠ₯ ν•­λͺ©μ„ μ§€μ›ν•©λ‹ˆκΉŒ?

에 λ§Œλ“  2018λ…„ 01μ›” 10일  Β·  6μ½”λ©˜νŠΈ  Β·  좜처: handlebars-lang/handlebars.js

ES6 ν™˜κ²½μ—μ„œ ν•Έλ“€λ°”λ₯Ό μ‚¬μš©ν•  경우 λ‚΄μž₯된 each ν—¬νΌμ˜ μ–΄λ ˆμ΄μ™€ μ œλ„€λ¦­ 객체만 μ§€μ›ν•˜λŠ” ν•œκ³„κ°€ μžˆμ–΄ λΆˆνŽΈν•©λ‹ˆλ‹€. 이 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ λ°°μ—΄, 지도, 집합, μ‚¬μš©μž μ •μ˜ 반볡 κ°€λŠ₯ 개체 및 일반 개체λ₯Ό μ§€μ›ν•˜λŠ” 자체 λ²„μ „μ˜ each λ„μš°λ―Έλ₯Ό λ“±λ‘ν•˜κΈ° μ‹œμž‘ν–ˆμŠ΅λ‹ˆλ‹€. κ·Έ λ„μš°λ―ΈλŠ” μ•„λž˜μ— μžˆμŠ΅λ‹ˆλ‹€.

λ‚΄μž₯된 each λ„μš°λ―Έμ—μ„œ μ΄λŸ¬ν•œ μœ ν˜•μ˜ λͺ©λ‘μ— λŒ€ν•œ 지원을 λ„μž…ν•  κ³„νšμ΄λ‚˜ 의ν–₯이 μžˆμŠ΅λ‹ˆκΉŒ? λ‚˜λŠ” ν•Έλ“€λ°”κ°€ 폴리필을 ν”Όν•˜λŠ” 것을 λͺ©ν‘œλ‘œ ν•œλ‹€λŠ” 것을 μ΄ν•΄ν•˜κ³  λΈŒλΌμš°μ € 지원을 μ†μƒμ‹œν‚€μ§€ μ•Šκ³  μƒˆ λ„μš°λ―Έκ°€ μž‘λ™ν•˜λ„λ‘ λ§Œλ“œλŠ” μœ μΌν•œ 방법은 ν™˜κ²½μ˜ κΈ°λ³Έ λ˜λŠ” 사전 폴리필 지원에 따라 λ‹€μ–‘ν•œ λͺ©λ‘ μœ ν˜•μ— λŒ€ν•œ 지원을 μ μ§„μ μœΌλ‘œ ν™œμ„±ν™”ν•˜λŠ” 것이라고 μƒμƒν•˜κΈ° λ•Œλ¬Έμ— μ§ˆλ¬Έν•©λ‹ˆλ‹€. 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 μ œλŒ€λ‘œ μ§€μ›ν•˜μ§€ μ•ŠλŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. ν˜„μž¬ [key, value] Map 의 _entry_ 인 반볡 ν•­λͺ©μ„ μƒμ„±ν•˜λŠ” 반면 μœ„μ˜ 예제 μ½”λ“œλŠ” 반볡 ν•­λͺ©μ„ value 둜 λ§Œλ“€κ³  @key , λ‚΄κ°€ _μƒκ°ν•˜λŠ”_ λ°”λžŒμ§ν•œ κ²ƒμž…λ‹ˆλ‹€. λ‚˜μ—κ²Œ λ°”λžŒμ§ν•˜λ‹€!

λ˜ν•œ ν‘œν˜„μ‹μ€ ν˜„μž¬ Map λ₯Ό μ§€μ›ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ {{person.myMap.myMapKey}} 라고 말할 수 μ—†μŠ΅λ‹ˆλ‹€. λ‚˜λŠ” μ§€κΈˆ 이 λ¬Έμ œμ— λŒ€ν•΄ 더 깊이 νŒŒκ³ λ“€κ³  μžˆλ‹€.

runtime.js $에 lookupProperty λ₯Ό μΆ”κ°€ν•˜λ©΄ Map μ—μ„œ 속성을 μ‘°νšŒν•  수 μžˆμŠ΅λ‹ˆλ‹€.

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

이런 지원을 μΆ”κ°€ν•˜λ €λŠ” μš•κ΅¬κ°€ μžˆμŠ΅λ‹ˆκΉŒ?

@karlvr λ‚˜λŠ” λ‹Ήμ‹ μ˜ μ œμ•ˆμ΄ 쑰사할 κ°€μΉ˜κ°€ μžˆλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ λ‚˜λŠ” 그것에 λŒ€ν•΄ λ…Όμ˜ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€.

@karlvr 은 지도 지원에 λŒ€ν•œ μƒˆλ‘œμš΄ 문제λ₯Ό μ‹œμž‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 이 문제의 μΌλΆ€λŠ” 이미 ν•΄κ²°λ˜μ—ˆμœΌλ©° κΉ¨λ—ν•œ μ‹œμž‘μ„ ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€.

@nknapp λΉ λ₯Έ λ‹΅λ³€ κ°μ‚¬ν•©λ‹ˆλ‹€. 방금 μ œμ•ˆλœ λ³€κ²½ μ‚¬ν•­μœΌλ‘œ PR을 ν–ˆμŠ΅λ‹ˆλ‹€. κ±°κΈ°μ—μ„œ λ…Όμ˜ν•  수 μžˆμ„κΉŒμš”? #1679

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰