【问题标题】:How to use path from within each clause as helper argument in handlebars.js如何使用每个子句中的路径作为handlebars.js中的辅助参数
【发布时间】:2016-06-05 05:26:03
【问题描述】:

我有以下场景

    {{#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 是一个辅助函数,它返回一个字符串数组,该数组是所有特征的串联。

我该如何正确写出上面的语句?

从每个子句中,我可以通过转义每个上下文来访问 setra.features 和 lion.features:

{{#each (concatArray setra.features lion.features)}}
{{../setra.features}} <!-- is accessible -->
{{/each}}

但是一旦我想在我的辅助函数contains 中使用任何一个作为参数,它会给我带来错误,具体取决于我尝试实现它的方式。上面的示例目前给我一个“无法读取未定义的属性 'includeZero'”错误,这似乎很可能是因为路径没有正确评估。

辅助函数如下:

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;

【问题讨论】:

    标签: templates nested handlebars.js helpers


    【解决方案1】:

    第一个问题是#if 之后的所有项目都被视为Handlebars #if block helper 的单独参数。 #if 需要一个参数,一个布尔表达式。

    Handlebars 支持subexpressions。来自文档:

    Handlebars 提供对子表达式的支持,它允许您 在一个小胡子中调用多个助手,并传入 内部助手调用的结果作为外部助手的参数。 子表达式由括号分隔。

    按照这些说明,模板中的#if 块必须更新为以下内容:

    <td>{{#if (contains ../setra.features this)}}YES{{/if}}</td>
    <td>{{#if (contains ../lion.features this)}}YES{{/if}}</td>
    

    现在运行代码不应引发“includeZero”错误。但是,仍然存在一个问题。似乎contains 助手总是在通过../setra.features 时返回true

    这是因为concatArray 助手正在改变setra.features 的值。事实上,“concatArray”修改了它的第一个数组参数,使其值成为所有“连接”数组的结果。 (请注意,您的助手并非严格意义上的“连接”,因为它还会删除重复元素。)

    要解决这个问题,我们需要concatArray 修改其第一个数组参数的副本,而不是修改第一个数组参数本身。有a few ways to do this,不过我会用JavaScript的Array.prototype.concat

    //var newArray = array1;
    var newArray = [].concat(array1);
    

    最后,我会稍微重构您的 contains 助手,只是为了清洁。我觉得下面的更漂亮:

    var contains = function (array, string) {
        return (Array.isArray(array) && array.indexOf(string) > -1);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-31
      • 1970-01-01
      • 2018-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-22
      相关资源
      最近更新 更多