我应该如何在交互式 Web 应用程序中实现 OOP 模式(借助 jQuery)?
有时,使用 jQuery 会导致您滥用其功能(至少对我来说是这样,因为它的选择器匹配功能)。到处都有事件处理程序。实用功能无处不在。代码一致性几乎不存在。我想通过实现 OOP 模式来缓解这个问题,但由于我有 C++ 和 python 背景,在 javascript 中实现它让我有点奇怪。
下面的代码使用 OOP 模式,但我不完全确定我的实现是否是好的实践。我怀疑我的实现的原因是因为 我的上一个 stackoverflow 问题。我知道他评论的只是我的代码中的一个特定细节,但这也让我想知道我在代码中实现的其他模式。
如果您能指出我的模式中的缺陷和陷阱和/或有任何建议,我将非常感激。非常感谢。
(此代码是我正在开发的代码的简化,但想法相似)
$(function(){
var stream = new Stream();
});
/* Stream Class
------------------------------------------*/
function Stream(){
// Disables multiple Stream objects
if (this.singleton)
return
else
this.__proto__.singleton = true;
this.elements = jQueryMapping(this.selectors) // Converts a map of selectors to a map of jQuery objects
this.initEvents();
}
Stream.prototype.singleton = false;
Stream.prototype.selectors = {
stream : '#stream',
post_content : '#post-content',
add_post: '#add-post',
// ... more action selectors
}
Stream.prototype.initEvents = function(){
this.elements.add_post.click(this, this.addPost);
// ... more action event-listeners
}
Stream.prototype.addPost = function(e){
var self = e.data;
var post_content = self.elements.post_content.val();
if (post_content)
self.elements.stream.append(new Post(post_content));
}
/* Post Class
------------------------------------------*/
function Post(post_content){
this.$element = $('<li>')
.text(post_content)
.append('<button class="delete-post">Delete</button>');
this.elements = jQueryMapping(this.selectors, this.$element);
this.initEvents();
return this.$element;
}
Post.prototype.selectors = {
delete_post: 'button.delete-post',
// ... more action selectors
}
Post.prototype.initEvents = function(){
this.elements.delete_post.click(this.deletePost);
// ... more action event-listeners
}
Post.prototype.deletePost = function(){
$(this).parent().slideUp();
}
/* Utils
------------------------------------------*/
function jQueryMapping(map, context){
// Converts a map of selectors to a map of jQuery objects
var $map = {};
$.each(map, function(key, value){
$map[key] = (context) ? $(value, context) : $(value);
});
return $map;
}
Sometimes, using jQuery induces you to abuse its power (at least for me because of its selector matching capability). Event handlers here and there. Utility functions here and everywhere. Code coherence can almost seem nonexistent. I want to alleviate that problem by implementing OOP patterns, but since I have C++ and python background, implementing it in javascript is weirding me out a little bit.
The code below uses OOP patterns, but I'm not entirely sure if my implementations are good practices. The reason I'm doubting my implementations is because of the 3rd comment in my last stackoverflow question. I know it's only one certain detail in my code he commented on, but it also makes me wonder about the other patterns I'm implementing in my code.
I would really appreciate if you could point out the flaws and pitfalls in my patterns and/or if you have any suggestions. Many thanks in advance.
(this code is an simplification of something I'm developing, but the idea is similar)
$(function(){
var stream = new Stream();
});
/* Stream Class
------------------------------------------*/
function Stream(){
// Disables multiple Stream objects
if (this.singleton)
return
else
this.__proto__.singleton = true;
this.elements = jQueryMapping(this.selectors) // Converts a map of selectors to a map of jQuery objects
this.initEvents();
}
Stream.prototype.singleton = false;
Stream.prototype.selectors = {
stream : '#stream',
post_content : '#post-content',
add_post: '#add-post',
// ... more action selectors
}
Stream.prototype.initEvents = function(){
this.elements.add_post.click(this, this.addPost);
// ... more action event-listeners
}
Stream.prototype.addPost = function(e){
var self = e.data;
var post_content = self.elements.post_content.val();
if (post_content)
self.elements.stream.append(new Post(post_content));
}
/* Post Class
------------------------------------------*/
function Post(post_content){
this.$element = $('<li>')
.text(post_content)
.append('<button class="delete-post">Delete</button>');
this.elements = jQueryMapping(this.selectors, this.$element);
this.initEvents();
return this.$element;
}
Post.prototype.selectors = {
delete_post: 'button.delete-post',
// ... more action selectors
}
Post.prototype.initEvents = function(){
this.elements.delete_post.click(this.deletePost);
// ... more action event-listeners
}
Post.prototype.deletePost = function(){
$(this).parent().slideUp();
}
/* Utils
------------------------------------------*/
function jQueryMapping(map, context){
// Converts a map of selectors to a map of jQuery objects
var $map = {};
$.each(map, function(key, value){
$map[key] = (context) ? $(value, context) : $(value);
});
return $map;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我相信你的代码设计过度了。我已经重新考虑并简化了它,如此处所示。如果您确实想要一个繁重的 OOP 设置,我建议您使用客户端 MVC(Backbone、knockout 等)构造来正确完成它或保持轻量级。
我将继续对您的代码提供一般反馈。
没有理由使用这样的单例。使用
.__proto__
也非常不好,我会推荐这样的模式。
没有必要像原型上那样存储数据的哈希值。
您可以将其包含为默认哈希值。
您的效用函数可以稍微优化。
这可以重写为
因为如果
context
未定义,您只需传递一个未定义的参数,这与不传递参数相同。I believe your code is over engineered. I've re factored and it simplified it as can be seen here. If you really want a heavy OOP setup I recommend you use a clientside MVC (Backbone, knockout, etc) construct to do it properly or keep it light instead.
I'll proceed with general feedback on your code.
There is no reason to use a singleton like this. It's also very bad to use
.__proto__
I would recommend pattern like this instead.
Storing a hash of data like that on the prototype is unneccesary.
You can include this as a defaults hash instead.
Your utility function could be optimised slightly.
This could be rewritten as
Since if
context
is undefined you just pass in an undefined paramater which is the same as passing in no parameter.该标题为“适合初学者”,但我发现此部分 关于设计模式,以及 本节关于使用 jQuery 的设计模式很有用。
The title of this reads "for beginners", but I've found this section on design patterns, and this section on design patterns using jQuery useful.