如何使用每个子句中的路径作为 handlebars.js 中的辅助参数
How to use path from within each clause as helper argument in handlebars.js
我有以下场景
{{#each (concatArray setra.features lion.features)}}
<tr>
<td><h4 class="ui header">{{this}}</h4></td>
<td>{{#if contains ../setra.features this}}YES{{/if}}</td>
<td>{{#if contains ../lion.features this}}YES{{/if}}</td>
</tr>
{{/each}}
其中 concatArray
是一个辅助函数,returns 一个字符串数组,它是所有特征的串联。
如何正确编写上面的语句?
在 each 子句中,我可以通过转义 each 上下文来访问 setra.features 和 lion.features:
{{#each (concatArray setra.features lion.features)}}
{{../setra.features}} <!-- is accessible -->
{{/each}}
但是一旦我想在我的辅助函数 contains
中使用其中任何一个作为参数,它就会给我错误,具体取决于我尝试实现它的方式。上面的示例目前给我一个 "Cannot read property 'includeZero' of undefined" 错误,这似乎很可能是因为路径未正确评估。
辅助函数如下:
var contains = function(array, string){
if(array && array.indexOf(string) > -1){ return true; }
return false;
}
exports.contains = contains;
var concatArray = function(array1, array2){
var newArray = array1;
array2.forEach(function(element){
if(newArray.indexOf(element) < 0){
newArray.push(element);
}
});
return newArray;
}
exports.concatArray = concatArray;
第一个问题是 #if
之后的所有项目都被视为 Handlebars #if block helper 的单独参数。 #if
需要一个参数,一个布尔表达式。
车把支持 subexpressions。来自文档:
Handlebars offers support for subexpressions, which allows you to
invoke multiple helpers within a single mustache, and pass in the
results of inner helper invocations as arguments to outer helpers.
Subexpressions are delimited by parentheses.
按照这些说明,模板中的 #if
块必须更新为以下内容:
<td>{{#if (contains ../setra.features this)}}YES{{/if}}</td>
<td>{{#if (contains ../lion.features this)}}YES{{/if}}</td>
运行 代码现在不应抛出 "includeZero" 错误。但是,仍然存在问题。似乎 contains
助手 always returns true
当传递 ../setra.features
.
这是因为 concatArray
助手正在更改 setra.features
的值。事实上,“concatArray”修改了它的第一个数组参数,使其值成为所有 "concatenated" 个数组的结果。 (请注意,您的助手并不是严格意义上的 "concatentation",因为它还会删除重复元素。)
要解决此问题,我们需要 concatArray
修改其第一个数组参数的 copy,而不是修改第一个数组参数本身。有a few ways to do this, but I will use JavaScript's Array.prototype.concat:
//var newArray = array1;
var newArray = [].concat(array1);
最后,为了简洁起见,我会稍微重构一下您的 contains
助手。我认为以下更漂亮:
var contains = function (array, string) {
return (Array.isArray(array) && array.indexOf(string) > -1);
}
我有以下场景
{{#each (concatArray setra.features lion.features)}}
<tr>
<td><h4 class="ui header">{{this}}</h4></td>
<td>{{#if contains ../setra.features this}}YES{{/if}}</td>
<td>{{#if contains ../lion.features this}}YES{{/if}}</td>
</tr>
{{/each}}
其中 concatArray
是一个辅助函数,returns 一个字符串数组,它是所有特征的串联。
如何正确编写上面的语句?
在 each 子句中,我可以通过转义 each 上下文来访问 setra.features 和 lion.features:
{{#each (concatArray setra.features lion.features)}}
{{../setra.features}} <!-- is accessible -->
{{/each}}
但是一旦我想在我的辅助函数 contains
中使用其中任何一个作为参数,它就会给我错误,具体取决于我尝试实现它的方式。上面的示例目前给我一个 "Cannot read property 'includeZero' of undefined" 错误,这似乎很可能是因为路径未正确评估。
辅助函数如下:
var contains = function(array, string){
if(array && array.indexOf(string) > -1){ return true; }
return false;
}
exports.contains = contains;
var concatArray = function(array1, array2){
var newArray = array1;
array2.forEach(function(element){
if(newArray.indexOf(element) < 0){
newArray.push(element);
}
});
return newArray;
}
exports.concatArray = concatArray;
第一个问题是 #if
之后的所有项目都被视为 Handlebars #if block helper 的单独参数。 #if
需要一个参数,一个布尔表达式。
车把支持 subexpressions。来自文档:
Handlebars offers support for subexpressions, which allows you to invoke multiple helpers within a single mustache, and pass in the results of inner helper invocations as arguments to outer helpers. Subexpressions are delimited by parentheses.
按照这些说明,模板中的 #if
块必须更新为以下内容:
<td>{{#if (contains ../setra.features this)}}YES{{/if}}</td>
<td>{{#if (contains ../lion.features this)}}YES{{/if}}</td>
运行 代码现在不应抛出 "includeZero" 错误。但是,仍然存在问题。似乎 contains
助手 always returns true
当传递 ../setra.features
.
这是因为 concatArray
助手正在更改 setra.features
的值。事实上,“concatArray”修改了它的第一个数组参数,使其值成为所有 "concatenated" 个数组的结果。 (请注意,您的助手并不是严格意义上的 "concatentation",因为它还会删除重复元素。)
要解决此问题,我们需要 concatArray
修改其第一个数组参数的 copy,而不是修改第一个数组参数本身。有a few ways to do this, but I will use JavaScript's Array.prototype.concat:
//var newArray = array1;
var newArray = [].concat(array1);
最后,为了简洁起见,我会稍微重构一下您的 contains
助手。我认为以下更漂亮:
var contains = function (array, string) {
return (Array.isArray(array) && array.indexOf(string) > -1);
}