Handlebars.js: هل يمكنني استخدام عدة مساعدين في بطاقة واحدة؟

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

مثل {{ helper1 helper2 text }} ، فأنت تعلم أحيانًا أن مساعدًا واحدًا فقط لا يكفي للقيام بالعمل.

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

يبدو أن هذا يحتوي على دعم محلي باستخدام شيء مثل:

{{ helper1 (helper2 text) }}

ال 17 كومينتر

أعتقد أنه يجب أن تكون هناك طريقة لتداخل التعبيرات ، مثل هذا: {{headerText {{getTitle "my_page"}}}} .

هذا غير مدعوم حاليًا وليس لدي أي خطط لدعمه.

ومع ذلك ، يمكنك نظريًا إنشاء مساعد يستهلك عمدًا ويسلاسل مساعدين آخرين:

{{chain "helper1" "helper2" text}}

إذا كان شخص ما مهتمًا ، فقد قمت بإنشاء مثل هذا المساعد:

Handlebars.registerHelper('chain', function () {
    var helpers = [], value;
    $.each(arguments, function (i, arg) {
        if (Handlebars.helpers[arg]) {
            helpers.push(Handlebars.helpers[arg]);
        } else {
            value = arg;
            $.each(helpers, function (j, helper) {
                value = helper(value, arguments[i + 1]);
            });
            return false;
        }
    });
    return value;
});

يعمل مثل هذا:

{{chain "taxAdd" "formatPrice" this.product.price}}

Znarkus الذي يقدم تبعية لـ jQuery

jrajan لقد استخدمت jQuery.each ، فلا تتردد في إعادة كتابته مهما كانت تفضيلاتك.

إذا كان أي شخص مهتمًا بإصدار jQuery الحيادي:

Handlebars.registerHelper('chain', function() {
  var helpers = [];
  var args = Array.prototype.slice.call(arguments);
  var argsLength = args.length;
  var index;
  var arg;

  for (index = 0, arg = args[index];
       index < argsLength;
       arg = args[++index]) {
    if (Handlebars.helpers[arg]) {
      helpers.push(Handlebars.helpers[arg]);
    } else {
      args = args.slice(index);
      break;
    }
  }

  while (helpers.length) {
    args = [helpers.pop().apply(Handlebars.helpers, args)];
  }

  return args.shift();
});

هناك مشكلة واحدة في كلا التطبيقين جديرة بالملاحظة: إذا كانت أي من الوسيطات مقصودة كقيم ليتم تمريرها إلى المساعد ، ولكن أيضًا (قابلة للإكراه) على السلاسل التي تطابق اسم المساعد الحالي ، فستكون هناك نتائج غير متوقعة.

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

الأول يسمح لك بعمل شيء مثل هذا:
{{{chain 'join-strings' 'link-twitter-handles' '@' twitterUsername}}}
لكن شيئًا كهذا قد يؤدي إلى نتائج غير متوقعة:
{{{chain 'join-strings' 'link-twitter-handles' '@' 'join-strings' twitterUsername}}}

Handlebars.registerHelper 'chain', ->
    # Get rid of the options hash
    args = Array.prototype.slice.call arguments, 0, -1
    helpers = []
    argsForHelpers = null
    value = undefined

    _.each args, (arg, i) ->
        if Handlebars.helpers[arg]
            helpers.push Handlebars.helpers[arg]
        else if not value # Only call the helpers once
            value = arg
            unless argsForHelpers
                argsForHelpers = args[i+1..-1]
                argsForHelpers.unshift value
            _.each helpers, (helper) ->
                argsForHelpers[0] = value
                value = helper.apply null, argsForHelpers

    value

يحتوي هذا المثال الثاني على فاصل يتيح لـ chain تقسيم المساعدين عن الوسيطات.
سوف يفترض المساعد أن كل وسيطة قبل الفاصل هي عبارة عن مُساعد ويجب أن يتم تمرير كل الحجة الأخرى كحجج إلى المساعدين.

Handlebars.registerHelper 'chain', ->
    # Get rid of the options hash
    args = Array.prototype.slice.call arguments, 0, -1
    helpers = []

    for arg,i in args
        if arg is '--'
            argsForHelpers = args.slice i + 1
            value = argsForHelpers[0]
            break
        else
            helpers.push Handlebars.helpers[arg]

    _.each helpers, (helper) ->
        argsForHelpers[0] = value
        value = helper.apply null, argsForHelpers

    value

بالنظر إلى هذا النموذج:
{{{chain 'join-strings' 'link-twitter-handles' '@' 'join-strings' twitterUsername}}}
وهذا الكائن:
{twitterUsername: 'abc'}
يمكننا توقع نموذج مجمع مثل هذا:
<a href="https://twitter.com/join-stringsabc">@join-stringsabc</a>

لقد أخذت تطبيقcdata وقمت بتحويله إلى إصدار

/**
 * Takes an arbitrary number of arguments, the first of which is the operation type 'AND' or 'OR'.
 * Following that will be a list of block helper names prefixed by '!!'.
 * Calls each block helper with the remaining arguments.
 *
 * <strong i="7">@returns</strong> {string}  returns options.fn(this) or options.inverse(this) depending on result of each helper and operation type
 */
Handlebars.registerHelper('chainBlockHelpers', function() {
    var index, arg, helperResult, pass,
        helpers = [],
        args = Array.prototype.slice.call(arguments),
        argsLength = args.length,
        options = args[argsLength-1],
        operation = args.shift(),
        passVal = options.fn(this),
        failVal = options.inverse(this);

    if (operation !== 'AND' && operation !== 'OR')
        throw new Error ('chainBlockHelpers only supports "AND" or "OR" operations.')

    for (index = 0, arg = args[index]; index < argsLength; arg = args[++index]) {
        if (typeof arg == 'string' && arg.startsWith('!!') && Handlebars.helpers[arg.substr(2)]) {
            helpers.push(Handlebars.helpers[arg.substr(2)]);
        } else {
            args = args.slice(index);
            break;
        }
    }

    if (operation === 'AND') {
        pass = true;
        while (helpers.length) {
            helperResult = helpers.pop().apply(Handlebars.helpers, args);
            if (helperResult == failVal) {
                pass = false;
                break;
            }
        }
    } else {
        pass = false;
        while (helpers.length) {
            helperResult = helpers.pop().apply(Handlebars.helpers, args);
            if (helperResult == passVal) {
                pass = true;
                break;
            }
        }
    }

    return pass ? passVal : failVal;
});

يبدو أن هذا يحتوي على دعم محلي باستخدام شيء مثل:

{{ helper1 (helper2 text) }}

في بعض الحالات ، يمكنك جعل مساعديك يعملون مثل:

{{#helper1}}{{helper2}}content{{/helper2}}{{/helper1}}

Znarkus باستخدام طريقتك ، عندما أمرر مساعدين لهما سلاسل آمنة ، طبقت فواصل الشفرة الخاصة بي. في المرة الأولى التي أمرر فيها البيانات تأتي كسلسلة ، لكن المرشح الثاني الذي تم تمريره يبدو أنه كائن؟ يظهر في مصحح الأخطاء "na line break ثم السلسلة:" my value "؛ لست متأكدًا مما يفعله SafeString بالقيمة ، ولكن لا يبدو أن تمريره مرتين ينجح بشكل جيد.

    Handlebars.registerHelper('shortNumber', function (value) {
        //return new Handlebars.SafeString(iSpot.number.shortNumber(value)); // Breaks
        return iSpot.number.shortNumber(value);  // Works
    });
    Handlebars.registerHelper('asDollars', function (value) {
        //return new Handlebars.SafeString(iSpot.number.asDollars(value)); // Breaks
        return iSpot.number.asDollars(value); // Works
    });

+1 نهج amwmedia - {{pluralize (titleize (humanize schema.name))}}

+1 التي تبدو وكأنها بناء جملة ونظيف ورائع.

+ 1amwmedia يعمل بشكل ممتاز

breandr /amwmedia أعمال النهج مثل سحر، ولكن فقط ث / س Handlebars.SafeString() كماcssagogo المذكورة أعلاه.

حتى تتمكن من القيام بشيء ما. مثل:

{{> partial text=(concat value (default extension 'PDF')) }}

شكرا

واجهت هذه المشكلة بنفسي. أعلم أنني تأخرت حقًا في هذا الأمر ، لكن لدي حل يناسبني. أرجو أن تسامحني إذا سبق ذكر ذلك (لم آخذ الوقت الكافي للتحقق). هذا ليس الحل الأفضل وهو ليس إجابة مباشرة لسؤالك من الناحية الفنية ولكنه حل للمشكلة (تشغيل وظائف متعددة على قيمة واحدة).

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

{{ function1 value }}

ملف مساعد

function2 (value) {
   // code
}

function1 (value) {
   // code
   function2(value)
   // code
   return value;
}

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

{{ chainer value }}

ملف مساعد

function1 (value) {
   // code
}
function2 (value) {
   // code
}
function3 (value) {
   // code
}
function4 (value) {
   // code
}

function chainer(value) {
   function1(value)
   function2(value)
   function3(value)
   function4(value)
   return value;
}

لم أفعل هذا بنفسي ولكني لا أرى سبب عدم نجاحه.

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

عودة إلى البرمجة الإجرائية :)

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