2017-08-01 93 views
1

我试图通过将视图和模型声明分离为模块(Browserify)来创建一个最小功能的Backbone.js应用程序。我的代码:在Browserify模块中的骨干视图 - 不工作

的index.html

<head> 
    <script src="bundle.js"></script> 
</head> 

<body> 
    <div id="myDiv">Loading...</div> 
</body> 

<script type="text/template" id="myTemplate"> 
    Test Content 
</script> 

Model.js

var Backbone = require('backbone') 
Backbone.$ = $ 

Model = Backbone.Model.extend({ 

}); 

module.exports = Model; 

View.js

var _ = require('underscore') 
var $ = require('jquery') 
var Backbone = require('backbone') 
Backbone.$ = $ 

View = Backbone.View.extend({ 
    el: '#myDiv', 
    template: _.template($('#myTemplate').html()), 
    initialize: function(){this.el.append(this.$el.html(this.template()));}, 
}); 

module.exports = View; 

main.js

var _ = require("underscore"); 
var Backbone = require("backbone"); 
var $ = require("jquery"); 
var View = require("./View"); 
var Model = require("./Model"); 
Backbone.$ = $; 

$(document).ready(function(){ 
    var model = new Model(); 
    var view = new View({model: model}); 
}); 

Browserify在控制台:

browserify main.js -o bundle.js -d 

错误:

Uncaught TypeError: Cannot read property 'replace' of undefined 
+0

一个想法 - 在你看来,你使用'this.el.append' ...你的意思是'this。$ el.append'?我不熟悉应用于原始DOM元素的'append'。 – arbuthnott

回答

1

即使没有Browserify您的代码将无法正常工作。

这是发生了什么事。当浏览器执行你的页面时,它会处理<script src="bundle.js"></script>,因此它会在加载bundle.js并在创建页面的其余部分之前立即执行这意味着,由当时的浏览器中执行这一行:

template: _.template($('#myTemplate').html()) 

scriptid设置为myTemplate元素尚不存在。因此,jQuery选择器不选择元素,并在空集上运行.html()返回undefined。所以上面的调用相当于运行_.template(undefined),这会导致您得到的错误。

解决方案:移动模板,使其位于加载bundle.jsscript元素之前。


由于arbuthnott在comment指出的那样,你也想this.$el.append而不是this.el.append。你没有在那里得到一个错误,因为你得到的错误代码没有得到运行的机会。

+0

谢谢,它现在有效。什么是最常见的做法:在bundle之前或之后加载bundle.js? – GlaceCelery

+1

最常见的做法是尽可能快地加载内容*,尽可能“最重要”。如果不能在'body'之前加载,因为依赖于仅在处理了'body'后才存在的元素,则必须在其后加载'bundle.js'。 – Louis

+0

您是否有npm domready作为解决方法的观点? – GlaceCelery