使用Handlebars.js减少代码

时间:2016-11-26 16:26:37

标签: javascript handlebars.js

我开始使用Handlebars和架构模式Model View ViewModel和我编写了这段代码:

var data = {
        currentPlayer: this._model.currentPlayer,
        line: [
            {
                row:
                [
                    {
                        caseNumber:1,
                        caseValue: this._model.getCaseState(0,0)
                    },
                    {
                        caseNumber:2,
                        caseValue: this._model.getCaseState(0,1)
                    },
                    {
                        caseNumber:3,
                        caseValue: this._model.getCaseState(0,2)
                    }
                ]
            },
            {
                row:[
                    {
                        caseNumber:4,
                        caseValue:this._model.getCaseState(1,0)
                    },
                    {
                        caseNumber:5,
                        caseValue:this._model.getCaseState(1,1)
                    },
                    {
                        caseNumber:6,
                        caseValue:this._model.getCaseState(1,2)
                    }
                ]
            },
            {
                row:[
                    {
                        caseNumber:7,
                        caseValue:this._model.getCaseState(2,0)
                    },
                    {
                        caseNumber:8,
                        caseValue:this._model.getCaseState(2,1)
                    },
                    {
                        caseNumber:9,
                        caseValue: this._model.getCaseState(2,2)
                    }
                ]
            }
        ]
    };
    var htmlContent = this._template(data);
    this._element.html(htmlContent);

使用以下模板:

<div>
    <h3>It is to player {{currentPlayer}}</h3>
    <table>
        {{#each line}}
        <tr>
            {{#row}}
            <td data="{{caseNumber}}" class="case{{caseValue}}">{{caseValue}}</td>
            {{/row}}
        </tr>
        {{/each}}
    </table>
</div>

此代码工作正常,但我问我是否无法减少它。所以我尝试在var数据中使用for循环,但我意识到我无法做到这一点。 我的另一个选择是在模板中使用if:

{{#each line}}
    <tr>
        {{#row}}
        {{#if caseValue}}
        <td data="{{caseNumber}}" class="case{{caseValue}}">O</td>
        {{else}}
        <td data="{{caseNumber}}" class="case{{caseValue}}">X</td>
        {{/if}}
        {{/row}}
    </tr>
{{/each}}

通过测试var caseValue的值。但是,由于caseValue10undefined的值,如果不检查案例,则所有单元格都会填充&#34}。 X&#34 ;. 所以,我无法找到一个紧凑的解决方案,目的是:

  • 一开始,所有TD标签都是空的。
  • 取决于返回getCaseState0填充的1的值 带有&#34; X&#34;或者&#34; O&#34;。

编辑:我使用以下代码管理getCaseState的不同值:

Handlebars.registerHelper('displayTd', function(data) {
        var result;
        if(data.caseValue === undefined) {
            result = '<td data="' + data.caseNumber + '"></td>';
            return new Handlebars.SafeString(result);
        } else if(data.caseValue === 1) {
            result = '<td data="' + data.caseNumber + '" class="case' + data.caseValue + '">X</td>';
            return new Handlebars.SafeString(result);
        } else {
            result = '<td data="' + data.caseNumber + '" class="case' + data.caseValue + '">O</td>';
            return new Handlebars.SafeString(result);
        }
    });

1 个答案:

答案 0 :(得分:1)

我将采用减少代码的第一步是使用循环来构建数据。 line对象中的数据遵循一个简单的模式,因此我们可以使用以下代码构建:

var numRows = 3;
var numColumns = 3;
var line = [];

for (var rowIndex = 0; rowIndex < numRows; rowIndex++) {
    line[rowIndex] = { row: [] };
    for (var columnIndex = 0; columnIndex < numColumns; columnIndex++) {
        line[rowIndex].row[columnIndex] = {
            caseNumber: ((rowIndex * numColumns) + columnIndex + 1),
            caseValue: getCaseState(rowIndex, columnIndex)
        };
    }
}

*请注意,您必须在现有模型对象上调用getCaseState

我们的data对象变为:

var data = {
    currentPlayer: this._model.currentPlayer,
    line: line
};

对于模板中的条件,我建议您创建自己的Handlebars助手。幸运的是,Handlebars有一个isEmpty实用程序方法,它返回true:

  
      
  • 长度为0的数组
  •   
  • 0以外的虚假值
  •   

这意味着我们可以使用此实用程序方法来检查我们的caseValue是否为undefined

Handlebars.registerHelper('getCharacter', function (caseValue) {
    return Handlebars.Utils.isEmpty(caseValue) ? '' : (caseValue === 0 ? 'X' : 'O');
});

然后我们以下列方式在模板中使用我们的新助手:

{{#each row}}
    <td data="{{caseNumber}}" class="case{{caseValue}}">{{getCharacter caseValue}}</td>  
{{/each}}