![](/img/trans.png)
[英]javascript - Coffeescript & Backbone.js - TypeError: this._ensureElement is not a function
[英]TypeError testing Backbone.js in CoffeeScript with Jasmine
我目前正在浏览Backbone.js上的PeepCode视频,但尝试全部用CoffeeScript而不是裸JavaScript编写。
到目前为止,一切都很好,除非当我尝试对代码运行Jasmine测试时,我遇到了一些TypeErrors:
TypeError: Cannot call method 'isFirstTrack' of undefined
TypeError: Cannot call method 'get' of undefined
我的CoffeeScript / Backbone文件如下所示:
jQuery ->
class window.Album extends Backbone.Model
isFirstTrack: (index) ->
index is 0
class window.AlbumView extends Backbone.View
tagName: 'li'
className: 'album'
initialize: ->
@model.bind('change', @render)
@template = _.template $('#album-template').html()
render: =>
renderedContent = @template @model.toJSON()
$(@el).html(renderedContent)
return this
茉莉花测试规范如下:
var albumData = [{
"title": "Album A",
"artist": "Artist A",
"tracks": [
{
"title": "Track A",
"url": "/music/Album A Track A.mp3"
},
{
"title": "Track B",
"url": "/music/Album A Track B.mp3"
}]
}, {
"title": "Album B",
"artist": "Artist B",
"tracks": [
{
"title": "Track A",
"url": "/music/Album B Track A.mp3"
},
{
"title": "Track B",
"url": "/music/Album B Track B.mp3"
}]
}];
describe("Album", function () {
beforeEach(function () {
album = new Album(albumData[0]);
});
it("creates from data", function () {
expect(this.album.get('tracks').length).toEqual(2);
});
describe("first track", function() {
it("identifies correct first track", function() {
expect(this.album.isFirstTrack(0)).toBeTruthy();
})
});
});
我猜想问题与CoffeeScript将所有内容包装在函数中有关。 当我从方程式中删除jQuery时,它工作正常。 奇怪的是,即使Jasmine告诉我TypeError: Cannot call method 'isFirstTrack' of undefined
如果我在页面的控制台中运行album.isFirstTrack(0)
,也TypeError: Cannot call method 'isFirstTrack' of undefined
但它会返回true
因此窗口确实可以访问变量和方法。
原因是范围界定,是的。
当您声明没有var
关键字且没有将其附加到另一个对象的album
变量时,您将在全局范围内创建一个变量。
这是一个坏主意。 您确实想限制创建的全局对象的数量,因为另一段JavaScript很容易覆盖您的数据或引起冲突等。
从这个角度来看,在测试中调用this.model
的想法是正确的。 问题是,你需要连接model
来this
是能够做到这一点。 很容易:
beforeEach(function () {
this.album = new Album(albumData[0]);
});
您所要做的就是说this.album = ...
,您就完成了。 现在您的测试将能够找到this.album
并且一切正常。
( 注意 :我相信Derick的答案是正确的-解释了TypeError: Cannot call method 'isFirstTrack' of undefined
消息的TypeError: Cannot call method 'isFirstTrack' of undefined
但此答案也可能是相关的。)
你说
当我从方程式中删除jQuery时,它工作正常。
这意味着如果您剪掉jQuery ->
,那么您的测试通过了吗? 如果是这样,那就不是范围问题; 这是一个代码顺序问题。 当您将函数传递给jQuery时,直到文档准备就绪,该函数才会执行。 同时,在定义Album
和AlbumView
类之前,您的测试将立即运行。
没有必要使用jQuery ->
包装器,因为您的类定义不依赖于任何现有的DOM元素。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.