javascript - 使用 Backbone 事件来切换 Collection View 属性或 jQuery.siblings()?

标签 javascript jquery backbone.js backbone-views backbone-events

设想以下简单模型和 View :

app.Messages = Backbone.Model.extend({
    defaults: function() {
        return {
            message: "an empty message…",
            messageActive: false
        };
    }
});

app.MessageView = Backbone.View.extend({
    tagName: "li",
    template: _.template($("#template").html()),
    events: {
        "click": "open"
    },
    initialize: function() {
        this.listenTo(this.model, "change", this.render);
        this.listenTo(this.model, "message:hide", this.hide);
    },
    render: function() {
        this.$el.html(this.template(this.model.toJSON()));
        return this;
    },
    open: function() {},
    hide: function() {
        this.model.set("messageActive", false);
        this.$el.removeClass("show-message");
    }
});

模型是集合的一部分,所有内容都由父 View 组合在一起(针对此问题进行了简化):

app.AppView = Backbone.View.extend({
    el: "#messages",
    initialize: function() {
        this.listenTo(app.messages, "message:show", this.foo);
    },
    foo: function(model) {
        var open = app.messages.where({messageActive: true});
        open.forEach(function(e, i) {
            if (model != e) {
                e.trigger("message:hide");
            }
        });
    },

在任何给定时间只能激活该集合中的一条消息。这意味着只要单击关闭的消息,任何打开的消息都将被关闭。现在的问题涉及 app.MessageView.open() 的功能。恕我直言,它可以使用 jQuery.siblings() 来隐藏所有 sibling 的消息并显示自己的消息:

open: function() {
    this.$el
        .addClass("show-message")
        .siblings(".show-message")
        .removeClass("show-message");
}

我个人认为这个解决方案非常优雅,我只是不喜欢它需要知道它有 sibling 。我的其他实现将使用一个自定义事件,该事件被父 View (app.AppView.foo()) 拦截,然后在每个事件上调用 app.MessageView.close()打开消息:

open: function() {
    this.model.set("messageActive", true).trigger("message:show", this.model);
    this.$el.addClass("show-message");
}

这对我来说感觉有点“ Backbone ”,但似乎有点过度设计。 ;-)

我可以想到第三种可能性,其中父 View 简单地跟踪最后打开的模型本身并触发任何被模型 View 拦截的关闭事件(似乎易于管理但对我来说不是很 Backbone ;-) ).我已经在此处介绍了很多关于 SO 的博客文章和问题,但没有得出真正令人满意的结论。也许有人可以阐明这个具体问题。

最佳答案

编辑:完全错过了消息 View 上的点击事件,因此修改了我的答案。


您可以在点击 View 时触发模型上的点击事件,然后等待父 View 触发模型上的显示和隐藏事件。

app.MessageView = Backbone.View.extend({
    tagName: "li",
    template: _.template($("#template").html()),
    events: {
        "click": "isClicked"
    },
    initialize: function() {
        this.listenTo(this.model, "change", this.render);
        this.listenTo(this.model, "message:show", this.open);
        this.listenTo(this.model, "message:hide", this.hide);
    },
    render: function() {
        this.$el.html(this.template(this.model.toJSON()));
        return this;
    },
    isClicked: function(){
        this.model.trigger("message:clicked");
    },
    open: function() {
        this.model.set("messageActive", true);
        this.$el.addClass("show-message");
    },
    hide: function() {
        this.model.set("messageActive", false);
        this.$el.removeClass("show-message");
    }
});

您的父 View 现在负责在点击其中一个 subview 时向模型发送正确的事件。

app.AppView = Backbone.View.extend({
  el: "#messages",
  initialize: function() {
    this.listenTo(app.messages, "message:clicked", this.foo);
  },
  foo: function(model) {
    var open = app.messages.where({messageActive: true});
    open.forEach(function(e, i) {
        if (model != e) {
            e.trigger("message:hide");
        }
    });
   // Because we retrieved the currently active models before sending this event,
   // there will be no racing condition:
   model.trigger("message:show");
},

也许这不是实现这种事情的最短途径。但它完全是事件驱动和可定制的。

关于javascript - 使用 Backbone 事件来切换 Collection View 属性或 jQuery.siblings()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20920953/

相关文章:

javascript - moment.js - 转换祖鲁时间

javascript - $.support.cors 澄清吗?

javascript - Backbone : managing templates

mysql - 配置服务器在本地运行

javascript - AngularJS 中的 Controller 到 Controller

javascript - Mongoose 从查询中设置局部变量

c# - ASP.Net MVC : How to customize validation message showing

javascript - jQuery 时钟在 JSF2.2 中不起作用

javascript - 使用 backbone.js 获取集合(所有模型)的总和

javascript - 在 AJAX 之后调用 PHP 函数