2012-12-03 198 views
0

我对js和backbone.js非常陌生,我向你保证我已经在docs和这里进行了大量搜索。我正在尝试构建一个显示照片(最终是其他内容)的简单网站,并且我希望能够点击一张照片以查看与另一个视图/模板不同的“网页”。我似乎无法得到这个工作,现在我在我的路由器的photoById方法中得到一个“Uncaught TypeError:不能调用方法”得到“未定义”。代码如下...谢谢!backbone.js路由问题

// ------ main.js

var photoListTemplate = Handlebars.compile($('#photo-list-template').html()); 
var photoTemplate = Handlebars.compile($('#photo-template').html()); 
var navTemplate = Handlebars.compile($('#navigation-template').html()); 

var Photo = Backbone.Model.extend({ 
    defaults: function() { 
    return { 

    }; 
    }, 
    initialize: function(options) { 

    } 
}); 
var PhotoCollection = Backbone.Collection.extend({ 
    model: Photo 
}); 

var PhotoView = Backbone.View.extend({ 
    events: { 

    }, 

    //tagName: 'td', 
    className: 'photo', 
    template: photoTemplate, 

    initialize: function(options) { 
     _.bindAll(this, 'render'); 
     this.model.on('change', this.render); 
    }, 
    render: function() { 
     $(this.el).empty().append(this.template(this.model.toJSON())); 
     return this; 
    } 
}); 

var PhotoCollectionView = Backbone.View.extend({ 
    tagName: 'table', 
    className: 'photo-list', 
    template: photoListTemplate, 
    events: { 

    }, 
    initialize: function(options) { 
     this.collection.on('add remove', this.render, this); 
    }, 
    render: function() { 
     $(this.el).empty(); 
     this.collection.each(function(photo){ 
      $(this.el).append(new PhotoView({model: photo}).render().el); 
     }, this); 
     return this; 
    } 
}); 

var PhotoRouter = Backbone.Router.extend({ 
    routes: { 
     "": "list", 
     "photo/:id": "photoById" 
    }, 
    initialize: function(options) { 

    }, 

    allPhotos: function() { 
     this.photoList = new PhotoCollection(); 
     this.photoCollectionView = new PhotoCollectionView({collection: this.photoList}); 
     this.photList.fetch(); 
     $('#content').empty().append(this.photoCollectionView.render().el); 
    }, 

    photoById: function(id){ 
     this.photo = this.photoList.get(id); 
     this.photoView = new PhotoView({model: this.photo}); 
     $('#content').empty().append(this.photoView.render().el); 
    } 
}); 

var photos = null; 
$.getJSON('http://localhost:3000/photos.json', function(response){ 
    photos = new PhotoCollection(response); 
    $('#container').append(new PhotoCollectionView({collection: photos}).render().el); 
    var photoRouter = new PhotoRouter(); 
    Backbone.history.start(); 
}); 

/index.html的-----

<!DOCTYPE html> 
<head> 
    <meta charset="utf-8"> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 
    <title></title> 
    <meta name="description" content=""> 
    <meta name="viewport" content="width=device-width"> 

    <!-- Place favicon.ico and apple-touch-icon.png in the root directory --> 

    <link rel="stylesheet" href="css/normalize.css"> 
    <link rel="stylesheet" href="css/bootstrap.css"> 

    <link rel="stylesheet" href="css/main.css"> 
    <script src="js/vendor/modernizr-2.6.2.min.js"></script> 
</head> 
<body> 
    <!--[if lt IE 7]> 
     <p class="chromeframe">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> or <a href="http://www.google.com/chromeframe/?redirect=true">activate Google Chrome Frame</a> to improve your experience.</p> 
    <![endif]--> 

    <!-- Add your site or application content here --> 
    <!-- <p>Replace Me! Replace Me!</p> --> 

    <div class='container' id='container'> 
    </div> 

    <script type="text/x-handlebars-template" id='navigation-template'> 
     <div class='navbar'> 
      <div class='navbar-inner'> 
       <a class='brand' href=#>ohayon</a> 
       <ul class='nav'> 

       </ul> 
      </div> 
     </div> 
    </script> 

    <script type="text/x-handlebars-template" id='photo-template'> 
     <div class='lead'> 
     <a href='#photo/{{id}}'>{{name}}</a> 
     <img src='http://localhost:3000{{image.url}}' height='200' width='200'> 
     </div> 
    </script> 

    <script type="text/x-handlebars-template" id='photo-list-template'> 
     <div class='lead'> 
     <a href='#photos/{{id}}'>{{name}}</a> 
     <img src='http://localhost:3000{{image.url}}'> 
     </div> 
    </script> 

    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script> 
    <script>window.jQuery || document.write('<script src="js/vendor/jquery-1.8.2.min.js"><\/script>')</script> 
    <script src="js/plugins.js"></script> 

    <!-- If we want Boostrap components --> 
    <script src="js/bootstrap.js"></script> 

    <!-- Templating with Handlebars --> 
    <script src="js/handlebars.js"></script> 

    <!-- We Need Underscore.js --> 
    <script src="js/underscore.js"></script> 

    <!-- And Finally Backbone --> 
    <script src="js/backbone.js"></script> 

    <!-- Your Code goes here --> 
    <script src="js/main.js"></script> 

    <!-- Google Analytics: change UA-XXXXX-X to be your site's ID. --> 
    <script> 
     var _gaq=[['_setAccount','UA-XXXXX-X'],['_trackPageview']]; 
     (function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0]; 
     g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js'; 
     s.parentNode.insertBefore(g,s)}(document,'script')); 
    </script> 
</body> 
</html> 

回答

2

你得到它编码的方式,有没有保证this.photoList将在您尝试在photoById中使用它时创建。您可能需要在路由器的初始化函数来创建它:

initialize: function(options) { 
    this.photoList = photos; 
}, 

而且从allPhotos删除几行 - 你不想重新创建PhotoCollection或致电fetch,因为它已经创建并在人口您的应用的第一步。应该是这样的:

allPhotos: function() { 
    this.photoCollectionView = new PhotoCollectionView({collection: this.photoList}); 
    $('#content').empty().append(this.photoCollectionView.render().el); 
}, 

(另一个问题,你使用container有时和别人content

It's running here.(我使用了一些假的数据来测试。)