简体   繁体   English

backbone.js路由问题

[英]backbone.js routing issue

I am very new to js and backbone.js, and I assure you I have searched extensively in docs and on here. 我是js和backbone.js的新手,我向你保证我已经在文档和这里进行了广泛的搜索。 I am trying to build a simple site that displays photos (eventually other things) and I want to be able to click a photo to see a different 'page' with another view/template. 我正在尝试构建一个显示照片(最终其他东西)的简单网站,我希望能够点击照片以查看与另一个视图/模板不同的“页面”。 I cant seem to get this to work and now I am getting a "Uncaught TypeError: Cannot call method 'get' of undefined" in my router's photoById method. 我似乎无法让这个工作,现在我得到一个“未捕获的TypeError:无法在我的路由器的photoById方法中调用方法'获取'未定义”。 Code below... THANKS! 代码如下......谢谢!

//------ main.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 / ----- 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>

The way you've got it coded, there's no guarantee this.photoList will have been created by the time you attempt to use it in photoById . 您编写代码的方式,无法保证this.photoList将在您尝试在photoById使用时photoById You might want to create it in the router's init function: 您可能想在路由器的init函数中创建它:

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

Also remove a few lines from allPhotos -- you don't want to re-create PhotoCollection or call fetch , since it was already created and populated in the first step of your app. 同时从allPhotos删除几行 - 您不想重新创建PhotoCollection或调用fetch ,因为它已在应用程序的第一步中创建并填充。 Should look like this: 应该是这样的:

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

(One other problem, you're using container sometimes and content others.) (另外一个问题,你使用container有时和content等。)

It's running here. 它在这里运行。 (I used some dummy data to test with.) (我使用了一些虚拟数据进行测试。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM