Backbone Marionette - 根据传入数据更新视图对象

时间:2014-03-17 15:53:35

标签: javascript backbone.js marionette publish-subscribe updatemodel

我有一个应用程序,它根据实时传入的iq数据包更新到pubsub节点。

目前,当我收到我的请求时,我正在使用主干木偶来创建初始视图。这将使用模板创建一个对象,然后我需要将实时数据提供给。

我想使用主干木偶用实时数据更新此对象,但我不确定如何完成。

目前,当我收到pubsub节点的正确类型的iq时,我会得到我想要的信息,然后调用一个函数" updatewell"它更新了骨干从原始响应中创建的对象。

骨干是否能够从pubsub事件更新此对象?我怎么称呼它?

下面的编辑显示了我在updatewell功能中所做的工作。骨干牵线木偶可以处理所有这些吗?它不像"用新数据替换模板",我需要根据返回的内容隐藏/显示信息。

我使用主干木偶的主要问题是它不断创造新的物体。在updatewell代码中,您注意到我正在定义具有唯一ID的div,并根据该id(在IQ中返回到pubsub)进行更新。这意味着正确的对象总是被更新,我无法在主干木偶中找到它。

本质上,我需要告诉牵牛花:"这些是一组新的值,是否存在具有此值的模型?如果没有,请创建它,如果是,则使用其他值"

更新它

请询问更多信息。

我的代码如下(自2014年5月1日起简化):

Backbone Marionette代码:

InfoWell = Backbone.Model.extend({});

InfoWells = Backbone.Collection.extend({
    model : InfoWell
});

InfoWellView = Backbone.Marionette.ItemView.extend({
    template : "#template-infowell",
    tagName : 'div',
    className : 'alert alert-custom',

initialize: function () {
    this.$el.prop("id", this.model.get("datetime"));
},
});

InfoWellsView = Backbone.Marionette.CompositeView.extend({
    tagName : "div",
    id : "info-well-list",
    template : "#template-infowells",
    itemView : InfoWellView,

});

MainJs.addInitializer(function(options) {
    var aInfoWellsView = new InfoWellsView({
        collection : options.InfoWells
    });
    MainJs.InfoWellsContainer.show(aInfoWellsView);
});

var InfoWells = new InfoWells();

创建良好的响应代码:

    InfoWells.add(new InfoWell({
        id : datetime,
        datetime : datetime,
        title : title,
        body : body,
        comments : comments
    }));

Pubsub代码:

pubsubHandlerInfo = function(iq) {
    var date = $(iq).find('datetime').get()
    ...     
    MainJs.vent.trigger("updatewell", {
        datetime : datetime,
        title : title,
        body : body,
        comments : comments
    });
    return true;
}

EDIT Updatewell功能:

MainJs.vent.bind("updatewell", function(data) {
        var datetime = data.datetime;

        if (datetime.length) {
            $("#hidden-state").trigger('testactions');
            $('#hidden-state').bind('testactions', updateWell(data))
        }

        function updateWell(data) {

        $("#body-" + data.datetime).html(data.body);
        $("#comments-" + data.datetime).html(data.comments);

        if (data.title === "something1") {
            $("#"+data.datetime+"-Something1").unbind('click').click(something1Action)
        } else if (data.title === "something2") {
            $("#"+data.datetime+"-Something2").unbind('click').click(something2Action)
        }

        function something1Action() {MainJs.function1();}
        function something2Action() {MainJs.function2();}
    });

所以用语言来说,我试图做的是: 将 MainJs.vent.trigger(" updatewell",{)替换为 InfoWells.add(新InfoWell({)将新模型发送到主干网.Backbone will查看此模型并检查是否已存在具有日期时间值ID的模型。

作为第一步,如果有一个具有此ID的模型,我需要使用发送的新值更新模型中的两个div(正文和注释)。如果没有带有此ID的模型,我需要正常创建一个(现在可以正常工作)。

作为第二步,我需要检查标题的值并为标题div创建一个单击函数。

非常感谢您提供的任何帮助。

编辑: 正如Dmytro所提到的,我可以使用set和get,但我不确定这在这里是如何适用的。我在哪里告诉它获取现有ID以及如何为其设置新值?任何有关此文档的链接都会很棒。

解: 因此,了解get和set以及应用它的位置是更新主干模型的主要部分。

以下是我添加到pubsub处理程序中的代码,它正确地执行了该操作。

    var update = InfoWells.get(datetime);
    console.log(update);
    if (update !== undefined && update !== null){
        update.set({
title : title,
body : body,
comments : comments
        });
    };

对于那些想知道我在做什么的人。我创建了一个名为update的变量,它通过查看集合( InfoWells )并获取值为 datetime 的ID来获取它的值,从上面你可以看到是我为每个模型分配的唯一ID值。

然后我检查这个更新值是否确实存在,如果确实存在,我会调用 set 命令,该命令告诉它将这些新值发送到模型中提到的属性。请注意,我遗漏了 id ,因为我永远不会更新模型。

然后,正如Dmytro所说,当模型改变时,我将渲染添加到ItemView。

    modelEvents: {
        "change": "render"
    }

对我来说,要好好复制我的更新,下一步是使用 "更改:ATTRIBUTE" :function()

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

首先,Backbone.Model应表示数据的当前状态,而不是视图应将其呈现为HTML。直接更新HTML不是Marionette的方式。

如果您不想创建新模型,但在接收有关现有模型的数据时退出更新,您可以在集合中找到现有模型(使用,getfindfindWhere )并使用set更新新属性。

如果某些属性发生更改,则会在模型中触发change个事件。您可以使用modelEvents

收听此活动并重新呈现您的观点
InfoWellView = Backbone.Marionette.ItemView.extend({
    template : "#template-infowell",
    tagName : 'div',
    className : 'alert alert-custom',
    modelEvents: {
      'change': 'render'
    }
});

答案 1 :(得分:0)

如果我理解正确,您需要将一个项目添加到集合中,compositeView将自动呈现此项目(wiki)。

将处理程序设置为“updatewell”事件,如here