1

首先,一些背景

我的客户有一种“拆分视图”,意思是显示对象列表的侧面板和显示所选对象详细信息的主视图。每次用户单击列表中的对象时,都会调用 Backbone 的路由以导航到更新Session上的“选定”属性的 id ,这导致主视图更新 - 非常标准的东西。

问题

我希望客户端尽可能地响应,因此我试图利用 Meteor 的能力立即更新客户端,而无需等待服务器确认。

我的目标是每次创建对象时,列表主视图都会立即更新以反映新添加的对象。为了实现这一点,我创建了一个 Meteor.method create(),它使用 Collection.insert 并返回 id,以便我可以将它与我的 Route 一起使用。该方法在客户端和服务器之间共享,并从模板的事件处理程序中调用。

我的第一次尝试是将返回的 id 存储在事件处理程序的变量中,并在下一行更新Route ;由于某种原因,这不起作用,因为该方法返回了一个未定义的值。所以我尝试了一种不同的方法,而不是返回 id,我在方法中使用它来直接更新Route(如果 Meteor.isClient 当然)。这也不起作用,因为 Collection.insert 在客户端方法版本中返回的 id 与服务器版本中的不同。

第一种方法

Template.createDialog.events({
    'click #btn-dialog-create': function (event, template) {
        var objectId = Meteor.call('create');
        appRouter.navigate("object/id/" + objectId, {trigger:true});
    }
});

第二种方法

Meteor.methods({
    create: function () {
        var ObjectId = Objects.insert({name:'test'});
        if(Meteor.isClient){
            appRouter.navigate("object/id/" + objectId, {trigger:true});
        }
    }
});

如果有人知道发生了什么并且可以给我一些指导,那就太好了。对问题或建议的任何不同方法也将不胜感激。

谢谢

更新

所以我尝试了@Pent 的建议,得到了与第二种方法相同的结果。出于某种奇怪的原因,Meteor 决定忽略我的 id(使用Random.id()创建)并插入另一个对象。

所以我尝试了另一种方法,我只使用了一个简单的字符串值而不是 Random.id() 并且瞧 -它有效。给我猜个谜。

4

3 回答 3

1

答案更新:

这将是客户端和服务器方法:

Meteor.methods({
    create: function () {
        var id = Random.id();
        Objects.insert({_id: id, name:'test'});
        if(this.isSimulation) {
            appRouter.navigate("object/id/" + id, {trigger:true});
        }
    }
});

您可以从 Meteor 的派对示例中查看类似的模式:https ://github.com/meteor/meteor/blob/b28c81724101f84547c6c6b9c203353f2e05fbb7/examples/parties/model.js#L56

于 2013-10-28T20:59:46.523 回答
0

您的问题是由远程方法(即将在服务器上调用的方法)不简单地返回任何值的事实引起的。相反,它们接受将用于处理返回值的回调(请参阅文档)。因此,在您的第一个示例中,您可能应该执行以下操作:

Template.createDialog.events({
    'click #btn-dialog-create': function (event, template) {
        Meteor.call('create', function (error, result) {
            if (!error)
                appRouter.navigate("object/id/" + result, {trigger:true});
        });
    }
});

你还说:

我希望客户端尽可能地响应,因此我试图利用 Meteor 的能力立即更新客户端,而无需等待服务器确认。

我认为在这种情况下,您绝对应该等待服务器响应。id请注意,除非服务器提供给您,否则您不可能获得正确的对象。

解决此问题的一种可能方法是创建本地(客户端)集合:

// only on client
var temporary = new Meteor.Collection(null); // null name

您可以在其中存储“临时”新创建的对象,然后在用户单击save按钮后将它们保存到“真实”集合中。您可以实现您的路由器来响应 url,例如object/new/*在将这些对象保存到数据库之前访问这些对象。

于 2013-10-29T09:06:35.990 回答
0

这个问题的正确答案是定义一个负责创建唯一 id 的客户端方法(最好使用Random.id())并调用 Meteor.methods 的create()。这样,您可以立即获得该 id,而无需等待服务器生成一个。这里的技巧是在 Meteor.method之外生成 id ,这样 id 生成对于存根和实际的服务器方法都只发生一次。

create = function(){
    var id = Random.id();
    Meteor.call('create', id);
    return id;
}

Meteor.methods({
    create: function (id) {
        Objects.insert({_id: id, name:'test'});

        //more code...
    }
});


//and in the Template...
Template.createDialog.events({
    'click #btn-dialog-create': function (event, template) {
        var objectId = create();
        appRouter.navigate("object/id/" + objectId, {trigger:true});
    }
});
于 2013-10-31T10:37:09.397 回答