wie {{ helper1 helper2 text }}
, wissen Sie, dass manchmal nur ein Helfer nicht ausreicht, um die Arbeit zu erledigen.
Ich denke, es müsste eine Möglichkeit geben, Ausdrücke zu verschachteln, etwa wie folgt: {{headerText {{getTitle "my_page"}}}}
.
Das wird derzeit nicht unterstützt und ich habe auch nicht vor, es zu unterstützen.
Sie könnten jedoch theoretisch einen Helfer erstellen, der andere Helfer absichtlich verbraucht und verkettet:
{{chain "helper1" "helper2" text}}
Falls es jemanden interessiert, ich habe so einen Helfer erstellt:
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;
});
Funktioniert so:
{{chain "taxAdd" "formatPrice" this.product.price}}
@Znarkus , das eine Abhängigkeit von jQuery einführt
@jrajan Ich habe nur jQuery.each
können es nach Ihren Wünschen neu schreiben.
Wenn jemand an einer agnostischen jQuery-Version interessiert ist:
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();
});
Ein Problem bei beiden Implementierungen ist erwähnenswert: Wenn eines der Argumente als Werte gedacht ist, die an einen Helfer übergeben werden sollen, aber zufällig auch Zeichenfolgen sind, die dem Namen eines vorhandenen Helfers entsprechen, gibt es unerwartete Ergebnisse.
Hier sind zwei Implementierungen. Bei beiden können Sie im Gegensatz zu den vorherigen Beispielen mehrere Argumente an jeden Helfer senden.
Sie sind auch in Kaffeeschrift geschrieben und hängen von Unterstrich oder Lodash ab.
Mit der ersten können Sie Folgendes tun:
{{{chain 'join-strings' 'link-twitter-handles' '@' twitterUsername}}}
Aber so etwas würde zu unerwarteten Ergebnissen führen:
{{{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
Dieses zweite Beispiel hat ein Trennzeichen, mit dem chain
die Helfer von den Argumenten trennen lässt.
Der Helfer geht davon aus, dass jedes Argument vor dem Trennzeichen ein Helfer ist und alle anderen als Argumente an die Helfer übergeben werden sollen.
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
Angesichts dieser Vorlage:
{{{chain 'join-strings' 'link-twitter-handles' '@' 'join-strings' twitterUsername}}}
und dieses Objekt:
{twitterUsername: 'abc'}
Wir könnten eine kompilierte Vorlage wie diese erwarten:
<a href="https://twitter.com/join-stringsabc">@join-stringsabc</a>
Ich habe die Implementierung von
/**
* 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;
});
Dies scheint eine native Unterstützung zu haben, die Folgendes verwendet:
{{ helper1 (helper2 text) }}
In einigen Fällen können Sie Ihre Helfer wie folgt arbeiten lassen:
{{#helper1}}{{helper2}}content{{/helper2}}{{/helper1}}
@Znarkus Wenn
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- Ansatz - {{pluralize (titleize (humanize schema.name))}}
+1, das sieht nach einer schönen sauberen Syntax aus.
+1 @amwmedia Funktioniert perfekt danke
@breandr / @amwmedia Ansatz funktioniert wie ein Charme, aber nur ohne Handlebars.SafeString()
wie @cssagogo oben erwähnt.
Du kannst also etw tun. mögen:
{{> partial text=(concat value (default extension 'PDF')) }}
Danke
Ich bin selbst auf dieses Problem gestoßen. Ich weiß, dass ich wirklich spät dran bin, aber ich habe eine Lösung, die für mich funktioniert hat. Bitte verzeihen Sie mir, wenn dies bereits erwähnt wurde (ich habe mir nicht die Zeit genommen, nachzusehen). Dies ist nicht die coolste Lösung und technisch gesehen keine direkte Antwort auf Ihre Frage, aber eine Lösung des Problems (mehrere Funktionen auf einem Wert ausführen).
Ich bewahre alle meine Hilfsfunktionen in einer separaten Datei auf. Da sie sich alle an derselben Stelle befinden, kann ich den Wert an einen Helfer übergeben und dann einfach alle anderen Funktionen aufrufen, die ich in der Datei meiner Helferfunktion habe. So:
{{ function1 value }}
Helferdatei
function2 (value) {
// code
}
function1 (value) {
// code
function2(value)
// code
return value;
}
Dies ist natürlich eine einfache Möglichkeit, beliebig viele Funktionen nutzen zu können. Sie könnten sogar eine Basisfunktion festlegen, die als Ihr "Chainer" fungiert.
{{ chainer value }}
Helferdatei
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;
}
Ich habe das selbst noch nicht gemacht, aber ich sehe nicht, warum es nicht funktionieren sollte.
Hinweis Sie müssen nur die Funktionen, die Sie in Ihrem HTML-Code verwenden möchten, als Lenker-Helfer registrieren. Ich persönlich habe meine alle registriert, weil ich sie unabhängig voneinander verwende, aber Sie müssen es nicht, wenn Sie nicht davon ausgehen, dass Sie es direkt verwenden müssen.
Ein Rückblick auf die prozedurale Programmierung :)
Hilfreichster Kommentar
Dies scheint eine native Unterstützung zu haben, die Folgendes verwendet:
{{ helper1 (helper2 text) }}