gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:17:57 24 4
gpt4 key购买 nike

设想以下简单模型和 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com