把手错误

时间:2017-08-05 16:42:32

标签: javascript handlebars.js

我已经设置了把手并且它运行正常,但是当我包含我的“添加”时。方法并尝试运行它抛出错误的render方法:

"您必须将字符串或Handlebars AST传递给Handlebars.compile。你通过了undefined"

不太清楚为什么......

HTML

<div id="to-do-app"></div>
<input id="add-to-do-value" type="text" placeholder="Add to do">
<button id="add-to-do">Add</button>
<script type="text/javascript" src="js/handlebars.js"></script>
<script id="to-do-template" type="text/template">
    <ul>
        {{#this}}
        <div>
            <li>{{value}}</li>
        </div>
        {{/this}}
    </ul>
</script>
<script type="text/javascript" src="js/app.js"></script>

JS

(function() {
    var toDo = {
        data: [],
        cacheDom: function() {
            this.toDoApp = document.getElementById('to-do-app');
            this.toDoTemplate = document.getElementById('to-do-template');
            this.addToDo = document.getElementById('add-to-do');
            this.addToDoValue = document.getElementById('add-to-do-value');
        },
        render: function() {
            this.toDoTemplate = Handlebars.compile(this.toDoTemplate.innerHTML);
            this.toDoApp.innerHTML = this.toDoTemplate(this.data);
        },
        bindEvents: function() {
            this.addToDo.addEventListener("click", this.add.bind(this));
        },
        add: function() {
            var toDoValue = this.addToDoValue.value;
            if(toDoValue) {
                var toDoObj = {
                    value: toDoValue
                }
            this.data.push(toDoObj);
            }
            this.render();
        },
        init: function() {
            this.cacheDom();
            this.bindEvents();
            this.render();
        }
    }

    toDo.init();
})();

1 个答案:

答案 0 :(得分:1)

init功能中,您拨打this.render()

render函数包含以下行:

this.toDoTemplate = Handlebars.compile(this.toDoTemplate.innerHTML);

因此,在初始化之后,this.toDoTemplate将保留对已编译模板的引用,而不是script元素。

在您add中,您再次致电render,但因为此时this.toDoTemplate保留了已编译的模板,this.toDoTemplate.innerHTML将为undefined而不是字符串,那些你会得到错误:

  

您必须将字符串或Handlebars AST传递给Handlebars.compile。你通过了未定义的

如何解决这个问题取决于用例。

解决方案是在cacheDom

中编译模板
 this.toDoTemplate = Handlebars.compile(document.getElementById('to-do-template'));

另一个是使用两个属性:

 this.toDoTemplateElement = document.getElementById('to-do-template')

 if( !this.toDoTemplate ) { // only compile it once and cache the compiled template
     this.toDoTemplate = Handlebars.compile(this.toDoTemplateElement.innerHTML);
 }

每次拨打render时编译模板很可能是您不想做的事情。