【问题标题】:How to re fetch backbone collection after collection create?集合创建后如何重新获取主干集合?
【发布时间】:2017-03-11 08:52:21
【问题描述】:

在我创建新模型时调用集合的create 函数后,谁能告诉我如何重新获取主干集合?

当我在创建新模型后在我的收藏上调用 fetch 时,有时我会得到那个模型,有时却没有。

我的问题是当我在我的集​​合中创建一个新模型时,我没有得到模型的 id,然后我无法立即更新它,我需要刷新页面,然后我得到了 id创建的模型。

我尝试使用listenTo,但我无法使用它,因为我需要将更多集合发送到一个函数。

我的引导模式视图,在保存时我正在创建我的模型,它会保存到数据库中,并且当我创建它时,我会在控制台中获取除模型 ID 之外的所有属性。

主干视图:

app.types.EditView = Backbone.View.extend({

    tagName: "div",

    $container: $('#containerEdit'),
    template: _.template($('#itemEdit-template').html()),

    events: 
    {
            "click .save": "save",
    },

    initialize: function(options)
    {   
            this.options = options;

            this.$container.html(this.render());

            this.start();
            this.end();
    },

    render: function() 
    {
            this.$el.html(this.template());
            return this.$el;
    },

    save: function() 
    {
            console.log("save");
            $('#openModal').modal('hide');
            var dan = this.model.dan_u_tjednu_usera.datum;
            var mjesec = this.model.dan_u_tjednu_usera.mjesecBrojevi;
            var godina = this.model.dan_u_tjednu_usera.godina;
            var start = $("#start").val();
            var end = $("#end").val();
            var user_id = this.model.user.id;

            this.model.shifts.create({day: dan, month: mjesec, year: godina, time_from: start, time_to: end, user_id: user_id});
            this.options.model.el.html($("<td href='#openModal' width='25%' align='center' class='list-group test' scope='row'>" + start + " - " + end + " " + "Admin" + "</td>"));
            this.model.shifts.fetch({sync: true});
            console.log("test", this.model.shifts);

    }

在这里您可以看到,在我的回复中,我在创建时没有获得 id 属性。

在这里您可以看到,当我单击我的单元格时,我记录了我的收藏,而我在这里没有创建模型的 id 属性。当我记录 this.model 时,我也没有得到它的 id 属性

【问题讨论】:

    标签: javascript backbone.js backbone.js-collections


    【解决方案1】:

    这是因为调用Collection.create时向服务器发送的请求是异步的,在服务器接收并响应请求之前,Javascript代码会继续执行。

    如果您想使用从服务器返回的 ID 更新模型,您可以在 Collection.create 调用中指定 {wait: true}。这意味着集合不会立即添加模型,而是仅在服务器响应(成功)时添加。

    在这种情况下,您应该在之后立即运行fetch,因为它还需要等待创建操作完成。您应该设置任何以下操作以在创建操作完成时触发。这是一个例子:

    var model = collection.create({field: 'abc'}, {wait: true});
    model.once('sync', function() { window.alert(model.id); });
    

    【讨论】:

    • 我没有得到创建模型的 ID,window.alert 没有被解雇我试过 console.log 并没有被解雇。当我创建模型时,我用我的 id 在我的数据库中获得了模型,但是当我控制台记录我的集合时,我得到了没有 id 的模型。
    • 您的服务调用是否返回新属性?
    • 是的,我在控制台中获取了新属性,但没有新模型的 id。当我获取两次时,我得到了它,但我不会获取两次,我想获取一次,或者如果可能的话,使用同步方法。
    • 看起来您需要修复服务调用,以便它返回新模型的 ID。
    • 什么是服务电话?
    【解决方案2】:

    Backbone's create

    方便在集合中创建模型的新实例。 相当于用属性的哈希实例化一个模型,保存 模型上传到服务器,然后将模型添加到集合中 成功创建。

    创建后无需获取集合,模型id 和任何其他字段会自动合并到其attributes 哈希中。

    模型创建后获取

    虽然mikeapr4 没有错,但他的例子可以改进。

    { wait: true } 是不必要的如果唯一的问题来自获取,而不是来自已经在集合中的模型。

    此外,应该避免使用once,因为它是“旧”方式,而应该使用listenToOnce。见Difference between ListenTo and on

    如果你真的想在创建模型后获取,那么在这里使用事件是多余的,相反,最好使用成功回调:

    save: function() {
        // ..snip...
        this.model.shifts.create({ /* ...snip... */ }, {
            context: this,
            success: this.onModelCreated
        });
    },
    
    onModelCreated: function() {
        // the model is now created and its attributes are up-to-date
        this.model.shifts.fetch();
    }
    

    代码的其他说明

    Backbone 中没有sync 选项。只有一个"sync" 事件和一个sync 函数。


    避免使用全局 jQuery 选择器(如 $('.class-name')),而当元素在视图元素内时,使用 this.$('.class-name')

    另外,缓存 jQuery 元素以避免对 find 方法进行昂贵的搜索。

    $("#start") 可以被缓存和重用。仅在重新渲染时重置缓存的元素。


    按照惯例,Backbone .render 函数应返回 this

    然后,您的渲染调用应如下所示:

    this.$container.html(this.render().el); // el is enough
    

    【讨论】:

    • 关于listenToOnce的好点,它是可取的,但是使用{wait: true}的建议是有效的,这意味着模型在它有效之前不会被添加到集合中(即有一个ID),这应该是修复的一部分,以防同一应用程序的其他部分使用该集合并可能对来自它的“添加”事件做出反应。
    • @mikeapr4 如果某个验证只能从服务器端获得,出错时删除模型。它让您的应用感觉响应更快,因为操作之间没有等待时间。这就像interpolation in multiplayer 游戏。
    • 从问题来看,对于没有 ID 的模型,应用程序的行为似乎不正确,因此最好等到它们准备好才能使用它们。一个示例可能是随后使用包含其 ID 的链接呈现模型以进行进一步操作(编辑/删除等)。但我们都在假设这个应用程序的工作原理。
    • @mikeapr4 我同意,wait 可以使用,但这里只是假设。我个人从来没有使用过它。
    • @mikeapr4 我更改了措辞以演示我如何假设问题出在提取,而不是由于过早填充的集合。
    猜你喜欢
    • 1970-01-01
    • 2013-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多