【问题标题】:Backbone.js and local storage . A "url" property or function must be specifiedBackbone.js 和本地存储。必须指定“url”属性或函数
【发布时间】:2012-12-25 23:12:39
【问题描述】:

我正在提高对 Backbone.js 的了解,并从教程中获取此代码示例。 (http://bardevblog.wordpress.com/2012/01/16/understanding-backbone-js-simple-example/)

这个例子暂时不会访问服务器,所以为了模拟从服务器检索数据,我有一个文件名movies.json。

我想做什么:

  • 在本地存储中添加 json 数据(使用 localStorage 适配器)
  • 为此,我正在使用 Backbone.ajaxSync,它由 localStorage 适配器赋予别名 Backbone.sync:我创建了方法 refreshFromServer () 来执行此操作
  • 这样做的原因是我试图实现一种只获取一次数据的方法(并且只在需要时刷新)

我的问题: 我在调用 refreshFromServer () 时遇到错误“未捕获的错误:必须指定 'url' 属性或函数”。 我不明白为什么,因为我设置了 url 集合。 (网址:“脚本/数据/movies.json”)

示例代码

var Theater = {
    Models : {},
    Collections : {},
    Views : {},
    Templates : {}
}

Theater.Models.Movie = Backbone.Model.extend({})
Theater.Collections.Movies = Backbone.Collection.extend({
    model : Theater.Models.Movie,
    localStorage : new Backbone.LocalStorage("MovieStore"), // Unique name within your app.
    url : "scripts/data/movies.json",
    refreshFromServer : function() {
        return Backbone.ajaxSync.apply(this, arguments);
    },
    initialize : function() {
        console.log("Movies initialize")
    }
});

Theater.Templates.movies = _.template($("#tmplt-Movies").html())

Theater.Views.Movies = Backbone.View.extend({
    el : $("#mainContainer"),
    template : Theater.Templates.movies,

    initialize : function() {

        this.collection.bind("reset", this.render, this);
    },

    render : function() {
        console.log("render")
        console.log(this.collection.length);

    }
})

Theater.Router = Backbone.Router.extend({
    routes : {
        "" : "defaultRoute"
    },

    defaultRoute : function() {
        console.log("defaultRoute");
        Theater.movies = new Theater.Collections.Movies()
        new Theater.Views.Movies({
            collection : Theater.movies
        });
        Theater.movies.refreshFromServer();
        //Theater.movies.fetch();
        console.log(Theater.movies.length)
    }
})

var appRouter = new Theater.Router();
Backbone.history.start();

注意事项:

  • 如果评论集合中的localStorage属性

    Theater.Models.Movie = Backbone.Model.extend({}) Theater.Collections.Movies = Backbone.Collection.extend({ 模型:剧院.模型.电影, //localStorage : new Backbone.LocalStorage("MovieStore") ... });

    然后在router调用正常的fetch方法

    Theater.Router = Backbone.Router.extend({ 路线:{ "" : "默认路由" },

    defaultRoute : function() {
    
        Theater.movies = new Theater.Collections.Movies()
        new Theater.Views.Movies({
            collection : Theater.movies
        });
        //Theater.movies.refreshFromServer();
        Theater.movies.fetch();
    }
    

    })

我可以在我的视图中正确地看到 json 列表

  • 如果我使用集合中的localStorage属性,然后调用标准的fetch()方法,我只看到一个空列表(我认为这是正常的,因为它是从本地存储中读取的并且是空的)

  • 该错误仅在使用方法 refreshFromServer () witch use Backbone.ajaxSync(backbone.sync 的别名)时发生

【问题讨论】:

    标签: javascript jquery backbone.js local-storage


    【解决方案1】:

    呃……我的错。 refreshFromServer 的实现来自我对您的earlier question. 的回答,它完全是无用的错误。

    Backbone.sync 需要参数(method, model, options),但就目前而言,它不能从refreshFromServer 获得它需要的东西,因为刷新方法只是向前发送它得到的任何arguments。抱歉弄错了。

    正确、有效的实现是:

    refreshFromServer : function(options) {
        return Backbone.ajaxSync('read', this, options);
    }
    

    它可以通过success / error 回调传递给options 散列来使用:

    this.collection.refreshFromServer({ success: function() { /* refreshed... */ });
    

    或通过 jqXHR Promise API:

    this.collection.refreshFromServer().done(function() { /* refreshed... */ })
    

    或者不注册回调并等待集合 reset 事件,就像您的示例中一样:

    this.collection.bind("reset", this.render, this);
    this.collection.refreshFromServer();
    

    这应该可行。如果没有,请告诉我。我也在上一个问题中修正了我的答案,以防有人偶然发现它。

    编辑:要在刷新后将数据保存到本地存储,您需要手动save 每个模型:

    var collection = this.collection;
    collection.refreshFromServer({success: function(freshData) {
        collection.reset(freshData);
        collection.each(function(model) {
            model.save();
        });
    }});
    

    【讨论】:

    • 非常感谢@fencliff 我尝试了你说的方式,现在我不再有错误“The” url “property ...”(这很好:))。但是现在当我调用 refreshFromServer () 时,我有一个空列表。使用 Chrome 控制台时,我注意到: - 正确调用的 Json 文件 - 创建了本地存储,但没有任何键/值 一个问题:当返回 json 时,它会自动放置在 localStorage 中吗?我在此代码示例以及我之前的问题中尝试了您的建议。
    • @Sandcar - 本地存储不会自动填充。您必须 .save() 集合中的每个模型。我编辑了我的答案,见上文。
    • 要在回调中获取对集合的引用,请根据我的编辑使用success 回调。
    • @Sandar,是的,你是对的。看看我的最后一个,希望是最后的编辑。看来我还是不够重视。另请注意,如果您的新数据没有本地存储中的某些模型,则不会自动清除它们。
    • 太棒了!奇迹般有效!我将在我的previous question 中添加评论,并附上指向此处的链接,以防有人偶然发现类似问题并需要帮助。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-11
    • 1970-01-01
    相关资源
    最近更新 更多