【问题标题】:Backbone Marionette - Updating view object based on incoming dataBackbone Marionette - 根据传入数据更新视图对象
【发布时间】:2014-04-22 22:25:53
【问题描述】:

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

目前,当我收到来自我的请求的响应时,我正在使用骨干木偶来创建初始视图。这会使用模板创建一个对象,然后我需要将实时数据输入到该对象中。

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

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

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

下面的编辑大致显示了我在 updatewell 函数中所做的事情。骨干木偶能应付这一切吗?不是“用新数据替换模板”那么简单,我需要根据返回的内容来隐藏/显示信息。

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

本质上,我需要告诉木偶:“这些是一组新的值,是否存在具有该值的模型,因为它的 id 存在?如果不存在,则创建它,如果存在,则使用另一个更新它价值观”

请询问更多信息。

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

骨干木偶代码:

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
    }));

发布订阅代码:

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

编辑 更新井函数:

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(new InfoWell({) 将新模型发送到主干。主干将看到这个模型并检查如果已经存在具有日期时间值 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"
    }

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

感谢您的帮助。

【问题讨论】:

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


    【解决方案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'
        }
    });
    

    【讨论】:

    • 嗨 Dmytro,抱歉,我不确定如何更新现有模型...您提到使用 get、find 或 findWhere 但我不知道我要查找什么.我如何告诉它找到“这个特定的模型”。我是否将我的自定义 ID 用于模型?还是骨干创造了一个?谢谢!
    • 默认主干模型的 id 是id 属性。但是您可以使用 idAttribute backbonejs.org/#Model-idAttribute 将任何属性指定为 id。您可以使用get as: var existsWell = wells.get(124);` 通过 id 找到现有模型
    • 嗨 Dmytro,很抱歉,迟到的回复已转移到另一个项目,但终于回到了这里。现在已经浏览了一个多星期,但我无法找到如何告诉木偶:“这些是一堆新值,请检查具有此 ID 的模型是否存在(ID 是日期时间)和如果是,则更新值,如果不是,则创建它”。据我了解,这就是木偶所做的,而您上面提到的证实了这一点(我不应该直接更新 HTML)。我已经更新了我的代码,以大大简化我实际需要做的事情。再次感谢。
    • 花了一段时间,但我明白了!用答案更新了主要内容
    【解决方案2】:

    如果我理解正确,你需要添加一个项目到集合中,compositeView 会自动渲染这个项目(wiki)。

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

    【讨论】:

    • 嗨 4ega,不幸的是,这导致了我之前遇到的相同问题,即它不断使用更新的信息创建新对象。为了提供更多信息(将添加到原始帖子中),函数“updatewell”根据返回的信息添加了许多新函数,它不像“用新文本替换此文本”那么简单。就个人而言,我不认为骨干木偶可以处理这个问题,但阅读文档似乎应该可以。
    猜你喜欢
    • 2015-07-27
    • 1970-01-01
    • 2020-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    相关资源
    最近更新 更多