id未在child.eval中定义

时间:2016-10-29 10:44:45

标签: javascript backbone.js

我正在编写我的第一个Backbone博客应用程序但是当我尝试添加新帖子时会抛出错误。

这是我的 app.js (所有主干相关组件都在此文件中):

_.templateSettings = {
    interpolate: /\{\{(.+?)\}\}/g
};

var Post = Backbone.Model.extend({});
var Posts = Backbone.Collection.extend({
    model : Post,
    url : "/posts"
});

var PostListView = Backbone.View.extend({
    tagName: "li",
    template: _.template("<a href='/posts/{{id}}'>{{title}}</a>"),
    events: {
        'click a': 'handleClick'
    },
    handleClick: function (e) {
        e.preventDefault();
        postRouter.navigate($(e.currentTarget).attr("href"),
            {trigger: true});
    },
    render: function () {
        this.el.innerHTML = this.template(this.model.toJSON());
        return this;
    }
});

var PostsListView = Backbone.View.extend({
    template: _.template("<h1>My Blog</h1><a href='/post/new' class='newPost'>New</a> <ul></ul>"),
    events: {
        'click .newPost': 'handleNewClick'
    },
    handleNewClick: function (e) {
        e.preventDefault();
        postRouter.navigate($(e.currentTarget).attr("href"),
            {trigger: true});
    },
    render: function () {
        this.el.innerHTML = this.template();
        var ul = this.$el.find("ul");
        this.collection.forEach(function (post) {
            ul.append(new PostListView({
                model: post
            }).render().el);
        });
        return this;
    }
});

var PostView = Backbone.View.extend({
    template: _.template($("#postView").html()),
    events: {
        'click a': 'handleClick'
    },
    render: function () {
        var model = this.model.toJSON();
        model.pubDate = new Date(Date.parse(model.pubDate)).toDateString();
        this.el.innerHTML = this.template(model);
        return this;
    },
    handleClick: function (e) {
        e.preventDefault();
        postRouter.navigate($(e.currentTarget).attr("href"),
            {trigger: true});
        return false;
    }
});

var PostFormView = Backbone.View.extend({
    tagName: 'form',
    template: _.template($("#postFormView").html()),
    initialize: function (options) {
        this.posts = options.posts;
    },
    events: {
        'click #submitPost': 'createPost',
        'click .back' : 'backButton'
    },
    render: function () {
        this.el.innerHTML = this.template();
        return this;
    },
    backButton: function (e) {
        e.preventDefault();
        postRouter.navigate($(e.currentTarget).attr("href"),
            {trigger: true});
        return false;
    },
    createPost: function (e) {
        e.preventDefault();
        var postAttrs = {
            content: $("#postText").val(),
            title: $("#postTitle").val(),
            pubDate: new Date(),
        };
        this.posts.create(postAttrs);
        postRouter.navigate("/", { trigger: true });
        return false;
    }
});

var PostRouter = Backbone.Router.extend({
    initialize: function (options) {
        this.posts = options.posts;
        this.main  = options.main;
    },
    routes: {
        '': 'index',
        'posts/:id': 'singlePost',
        'post/new': 'newPost'
    },
    index: function () {
        var pv = new PostsListView({ collection: this.posts });
        this.main.html(pv.render().el);
    },
    singlePost: function (id) {
        var post = this.posts.get(id);
        var pv = new PostView({ model: post });
        this.main.html(pv.render().el);
    },
    newPost: function () {
        var pfv = new PostFormView({ posts: this.posts });
        this.main.html(pfv.render().el);
    }
});

我的索引文件中也有一些视图模板:

<!DOCTYPE html>
<html>
<head>
    <title> Simple Blog </title>
</head>
<body>
<div id="main"></div>
<script src="/jquery.js"></script>
<script src="/underscore.js"></script>
<script src="/backbone.js"></script>
<script type="text/template" id="postFormView">
    <a href="/" class="back">All Posts</a><br />
    <input type="text" id="postTitle" placeholder="post title" />
    <br />
    <textarea id="postText"></textarea>
    <br />
    <button id="submitPost"> Post </button>
</script>
<script type="text/template" id="postView">
    <a href='/'>All Posts</a>
    <h1>{{title}}</h1>
    <p>{{pubDate}}</p>
    {{content}}
</script>
<script src="/app.js"></script>
<script>
    var postRouter = new PostRouter({
        posts: new Posts(<%- posts %>),
        main: $("#main")
    });
    Backbone.history.start({pushState: true});
</script>
</body>
</html>

查看帖子和主页工作正常,但当我尝试创建新帖子时,我从开发工具控制台收到此错误:

Uncaught ReferenceError: id is not defined
    at child.eval (eval at _.template (http://localhost:3000/underscore.js:1:1), <anonymous>:6:8)
    at child.template (http://localhost:3000/underscore.js:1214:21)
    at child.render (http://localhost:3000/app.js:27:34)
    at http://localhost:3000/app.js:48:16
    at Array.forEach (native)
    at Function._.each._.forEach (http://localhost:3000/underscore.js:79:11)
    at child.Collection.(anonymous function) [as forEach] (http://localhost:3000/backbone.js:956:24)
    at child.render (http://localhost:3000/app.js:45:25)
    at child.index (http://localhost:3000/app.js:118:27)
    at Object.callback (http://localhost:3000/backbone.js:1242:30)

服务器是一个简单的nodejs服务器,用于创建帖子的输出是这样的:

{"result":{"ok":1,"n":1},"ops":[{"content":"kljhlkjh","title":"jkhjklh","pubDate":"2016-10-29T10:21:47.793Z","id":12,"_id":"5814783b732bbe153461eca4"}],"insertedCount":1,"insertedId
s":["5814783b732bbe153461eca4"]}

1 个答案:

答案 0 :(得分:3)

错误在哪里?

首先,您需要找到导致错误的原因,以及它来自何处。

错误来自PostListView render函数中的以下行:

this.el.innerHTML = this.template(this.model.toJSON());

下划线的模板渲染会引发错误。归结为:

template: _.template("<a href='/posts/{{id}}'>{{title}}</a>"),

请参阅{{id}}?它是在错误发生时未定义的那个。

&#34; {{id}}未定义&#34; 是什么意思?

您正在传递this.model.toJSON()作为模板的数据。因此,这意味着this.model的{​​{1}}属性未定义尚未

为什么我的模型id尚未定义?

这是因为通过collection's create function创建新模型异步

id

如何在收集this.posts.create(postAttrs); // the model hasn't received an id from the server yet. postRouter.navigate("/", { trigger: true }); 电话后等待?

Backbone为大多数(如果不是全部)异步函数提供createsuccess个回调。

  

选项哈希需要errorsuccess个回调   传递error作为参数。

因此,您可以将(collection, response, options)功能更改为以下内容,添加createPost回调。

onPostCreated