我使用Handlebars .NET作为我的邮件模板,所以我在服务器端宽度ASP.NET MVC生成模板。我需要像这样的比较。但它做得不好?我能做什么?
//Product.ProdType is a enum property
{{#if (Product.ProdType=='BlaBlaBla')}}
<p>This is a test</p>
{{/if}}
答案 0 :(得分:5)
我遇到了同样的问题,我创建了一个辅助函数“ifCond”,它使用数值数据类型和字符串。它可以进行优化或扩展,以与其他类型一起使用。
Handlebars.RegisterHelper("ifCond",
(writer, context, args) =>
{
if (args.Length != 5)
{
writer.Write("ifCond:Wrong number of arguments");
return;
}
if (args[0] == null || args[0].GetType().Name == "UndefinedBindingResult")
{
writer.Write("ifCond:args[0] undefined");
return;
}
if (args[1] == null || args[1].GetType().Name == "UndefinedBindingResult")
{
writer.Write("ifCond:args[1] undefined");
return;
}
if (args[2] == null || args[2].GetType().Name == "UndefinedBindingResult")
{
writer.Write("ifCond:args[2] undefined");
return;
}
if (args[0].GetType().Name == "String")
{
string val1 = args[0].ToString();
string val2 = args[2].ToString();
switch (args[1].ToString())
{
case ">":
writer.Write(val1.Length > val2.Length ? args[3] : args[4]);
break;
case "=":
case "==":
writer.Write(val1 == val2 ? args[3] : args[4]);
break;
case "<":
writer.Write(val1.Length < val2.Length ? args[3] : args[4]);
break;
case "!=":
case "<>":
writer.Write(val1 != val2 ? args[3] : args[4]);
break;
}
}
else
{
float val1 = float.Parse(args[0].ToString());
float val2 = float.Parse(args[2].ToString());
switch (args[1].ToString())
{
case ">":
writer.Write(val1 > val2 ? args[3] : args[4]);
break;
case "=":
case "==":
writer.Write(val1 == val2 ? args[3] : args[4]);
break;
case "<":
writer.Write(val1 < val2 ? args[3] : args[4]);
break;
case "<=":
writer.Write(val1 <= val2 ? args[3] : args[4]);
break;
case ">=":
writer.Write(val1 >= val2 ? args[3] : args[4]);
break;
case "!=":
case "<>":
writer.Write(val1 != val2 ? args[3] : args[4]);
break;
}
}
以下是一些解释用法的单元测试:
var template = Handlebars.Compile("{{{ifCond test '>' 1 '>1' '<=1' }}}");
var data = new { test = 2 };
var result = template(data);
Assert.AreEqual(">1", result);
data = new { test = 0 };
result = template(data);
Assert.AreEqual("<=1", result);
template = Handlebars.Compile("{{{ifCond test '=' 1 'eq' 'not eq' }}}");
data = new { test = 1 };
result = template(data);
Assert.AreEqual("eq", result);
data = new { test = 0 };
result = template(data);
Assert.AreEqual("not eq", result);
template = Handlebars.Compile("{{{ifCond test '!=' 1 'diff' 'eq' }}}");
data = new { test = 2 };
result = template(data);
Assert.AreEqual("diff", result);
template = Handlebars.Compile("{{{ifCond str '!=' '' 'not empty' 'empty' }}}");
var datastr = new { str = "abc" };
result = template(datastr);
Assert.AreEqual("not empty", result);
template = Handlebars.Compile("{{{ifCond str '==' '' 'empty' 'not empty' }}}");
datastr = new { str = "" };
result = template(datastr);
Assert.AreEqual("empty", result);
希望它有所帮助,我也希望更好的实现,更优雅,我的解决方案有效,但我认为它可以更简洁的方式完成。
以下是模板中具有Int32值的用法示例:
{{ifCond MycountVariable '>' 1 'more than one' 'one'}}
这是一个在模板中包含String值的用法示例:
{{ifCond MyStringVariable '!=' '' MyStringVariable 'empty value'}}
答案 1 :(得分:1)
像你一样尝试做的逻辑必须是辅助函数。你不能将这样的关系运算符直接放入把手模板中。它是故意设计的。助手很容易创建和使用。请参阅http://handlebarsjs.com/#helpers更多信息。
hbs.registerHelper("IsSame", function(ProdType) {
if(ProdType == "BlaBlaBla") {
$('#HereText').append('<p>This is a test</p>');
}
});
在模板中执行此操作
<div class="row">
{{IsSame Product.ProdType}}
</div>
所以在这里你将你的值传递给辅助函数并进行比较..
答案 2 :(得分:0)
我尝试了@Matteo Conta的解决方案,但它不支持与文本结合的变量。所以我调整了一下以便于使用&amp;更好的支持变量。
<强>语法强>
{{#ifCond arg1 condition arg2}}
True clause {{variable}}
{{else}}
False clause {{variable}}
{{/ifCond}}
<强>代码强>
Handlebars.RegisterHelper("ifCond", (writer, options, context, args) => {
if (args.Length != 3)
{
writer.Write("ifCond:Wrong number of arguments");
return;
}
if (args[0] == null || args[0].GetType().Name == "UndefinedBindingResult")
{
writer.Write("ifCond:args[0] undefined");
return;
}
if (args[1] == null || args[1].GetType().Name == "UndefinedBindingResult")
{
writer.Write("ifCond:args[1] undefined");
return;
}
if (args[2] == null || args[2].GetType().Name == "UndefinedBindingResult")
{
writer.Write("ifCond:args[2] undefined");
return;
}
if (args[0].GetType().Name == "String")
{
var val1 = args[0].ToString();
var val2 = args[2].ToString();
switch (args[1].ToString())
{
case ">":
if (val1.Length > val2.Length)
{
options.Template(writer, (object)context);
}
else
{
options.Inverse(writer, (object)context);
}
break;
case "=":
case "==":
if (val1 == val2)
{
options.Template(writer, (object)context);
}
else
{
options.Inverse(writer, (object)context);
}
break;
case "<":
if (val1.Length < val2.Length)
{
options.Template(writer, (object)context);
}
else
{
options.Inverse(writer, (object)context);
}
break;
case "!=":
case "<>":
if (val1 != val2)
{
options.Template(writer, (object)context);
}
else
{
options.Inverse(writer, (object)context);
}
break;
}
}
else
{
var val1 = float.Parse(args[0].ToString());
var val2 = float.Parse(args[2].ToString());
switch (args[1].ToString())
{
case ">":
if (val1 > val2)
{
options.Template(writer, (object)context);
}
else
{
options.Inverse(writer, (object)context);
}
break;
case "=":
case "==":
if (val1 == val2)
{
options.Template(writer, (object)context);
}
else
{
options.Inverse(writer, (object)context);
}
break;
case "<":
if (val1 < val2)
{
options.Template(writer, (object)context);
}
else
{
options.Inverse(writer, (object)context);
}
break;
case "!=":
case "<>":
if (val1 != val2)
{
options.Template(writer, (object)context);
}
else
{
options.Inverse(writer, (object)context);
}
break;
}
}
});
示例用法
var template = Handlebars.Compile(@"{{#ifCond arg1 '>' arg2}}{{arg1}} is greater than {{arg2}}{{else}}{{arg1}} is less than {{arg2}}{{/ifCond}}");
var data = new { arg1 = 2 , arg2 = 1};
var result = template(data);
Assert.Equal("2 is greater than 1", result);
data = new { arg1 = 1, arg2 = 2 };
result = template(data);
Assert.Equal("1 is less than 2", result);
template = Handlebars.Compile(@"{{#ifCond arg1 '<' arg2}}{{arg1}} is less than {{arg2}}{{else}}{{arg1}} is greater than {{arg2}}{{/ifCond}}");
data = new { arg1 = 2, arg2 = 1 };
result = template(data);
Assert.Equal("2 is greater than 1", result);
data = new { arg1 = 1, arg2 = 2 };
result = template(data);
Assert.Equal("1 is less than 2", result);
template = Handlebars.Compile(@"{{#ifCond arg1 '=' arg2}}{{arg1}} is eq to {{arg2}}{{else}}{{arg1}} is not eq to {{arg2}}{{/ifCond}}");
data = new { arg1 = 1, arg2 = 1 };
result = template(data);
Assert.Equal("1 is eq to 1", result);
data = new { arg1 = 2, arg2 = 1 };
result = template(data);
Assert.Equal("2 is not eq to 1", result);
template = Handlebars.Compile(@"{{#ifCond arg1 '!=' arg2}}{{arg1}} is not eq to {{arg2}}{{else}}{{arg1}} is eq to {{arg2}}{{/ifCond}}");
data = new { arg1 = 2, arg2 = 1 };
result = template(data);
Assert.Equal("2 is not eq to 1", result);
template = Handlebars.Compile(@"{{#ifCond str '!=' ''}}not empty{{else}}empty{{/ifCond}}");
var datastr = new { str = "abc" };
result = template(datastr);
Assert.Equal("not empty", result);
template = Handlebars.Compile(@"{{#ifCond str '==' ''}}empty{{else}}not empty{{/ifCond}}");
datastr = new { str = "" };
result = template(datastr);
Assert.Equal("empty", result);
答案 3 :(得分:0)
我使用的是Handlebars.NET作者在其unit tests中所提交的方式,它的工作方式就像一种魅力:
Handlebars.RegisterHelper("ifCond", (writer, options, context, arguments) =>
{
if (arguments[0] == arguments[1])
{
options.Template(writer, (object)context);
}
else
{
options.Inverse(writer, (object)context);
}
});
(至少在Handlebars.NET 1.10.1中)。