Back navigation not reloading jwplayer in backbone js and rails 3 app-Collection of common programming errors
My app is a rails 3 app using backbone.js and jw player for playing a playlist of videos. The index_view for the videos has all the videos loaded into a playlist for jw player. My problem comes when I navigate away from the index page, let’s say to the show_view for an individual video. When I click the browser’s back button I get an error when the jw player tries to load again.
Uncaught TypeError: Object # has no method 'setup'
I believe the problem is that the template hasn’t loaded the html element that the player uses to instantiate itself. That’s my current theory. If you look in index_view.js.coffee
you see that in the render
method I use the JQuery $(document).read ->
method to load the player. If I remove that, the player doesn’t load and I see the same error.
Uncaught TypeError: Object # has no method 'setup'
This error can be reproduced simply by calling the jwplayer on a non-existant CSS id. ie jwplayer('non-existant-id').setup(...)
would produce the same error. I’m pretty new to backbone but I would assume that the JQuery document.ready method has no effect after the initial loading of the index page. The DOM is never reloaded once I’m using the #
routes, so when I navigate back to the index page, the id ‘my-video’ doesn’t yet exist so calling jwplayer('my-video')
produces an error. Is there any sort of Backbone.ready
method? 🙂
So here’s some code, lemme know if you need anything else:
index.html.erb
The rails view for videos
$(function() {
// Blog is the app name
window.router = new SeehearmeWebapp.Routers.VideosRouter({videos: , users: , questions: });
Backbone.history.start();
});
videos_router.js.coffee
class SeehearmeWebapp.Routers.VideosRouter extends Backbone.Router
initialize: (options) ->
@videos = new SeehearmeWebapp.Collections.VideosCollection()
@videos.reset options.videos
@users = new SeehearmeWebapp.Collections.UsersCollection()
@users.reset options.users
@playlist = []
@questions = options.questions
for i in [[email protected]]
video = @videos.models[i]
versions = video.attributes.versions[6]
images = video.attributes.thumbnails[0]
question = @questions[parseInt(video.attributes.question_id)-1]
if !(question == undefined)
title = question.text
else
title = ""
if !(versions == undefined)
creator_id = video.attributes.creator_id.toString()
@playlist.push {file: versions.url, creator_id: creator_id, gender: @users.get(creator_id).attributes.gender, question: title , image: images.url}
routes:
"new" : "newVideo"
"index" : "index"
":id/edit" : "edit"
":id" : "show"
".*" : "index"
newVideo: ->
@view = new SeehearmeWebapp.Views.Videos.NewView(collection: @videos)
$("#videos").html(@view.render().el)
index: ->
@view = new SeehearmeWebapp.Views.Videos.IndexView(videos: @videos, users: @users, playlist: @playlist)
$("#videos").html(@view.render().el)
show: (id) ->
video = @videos.get(id)
@view = new SeehearmeWebapp.Views.Videos.ShowView(model: video)
$("#videos").html(@view.render().el)
edit: (id) ->
video = @videos.get(id)
@view = new SeehearmeWebapp.Views.Videos.EditView(model: video)
$("#videos").html(@view.render().el)
index_view.js.coffee
SeehearmeWebapp.Views.Videos ||= {}
class SeehearmeWebapp.Views.Videos.IndexView extends Backbone.View
template: JST["backbone/templates/videos/index"]
playerHeight = '360'
playerWidth = '640'
defaultVersion = 0
playlist = []
initialize: () ->
@options.videos.bind('reset', @addAll)
playlist = @options.playlist
addAll: () =>
@options.videos.each(@addOne)
addOne: (video) =>
view = new SeehearmeWebapp.Views.Videos.VideoView({model : video})
@$("tbody").append(view.render().el)
render: =>
$(@el).html(@template(videos: @options.videos.toJSON() ))
@addAll()
$(document).ready ->
player = jwplayer('my-video')
player.setup({playlist: playlist, width: playerWidth, height: playerHeight, skin: "/jwplayer/skins/six/six.xml"})
return this
index.jst.ejs
Show Me:
Women and Men
seehear.me
meet her
show_view.js.coffee
SeehearmeWebapp.Views.Videos ||= {}
class SeehearmeWebapp.Views.Videos.ShowView extends Backbone.View
template: JST["backbone/templates/videos/show"]
render: ->
$(@el).html(@template(@model.toJSON() ))
return this
show_view.js.coffee
THIS IS A VIDEO
Back
Thanks!