我应该如何实现面向对象模式的交互式web应用程序(与jQuery的助手)
How should I implement OOP patterns to interactive web applications (with the aide of jQuery)?
有时,使用jQuery会导致您滥用它的功能(至少对我来说是这样,因为它的选择器匹配功能)。到处都有事件处理程序。这里到处都是效用函数。代码一致性几乎不存在。我想通过实现面向对象模式来缓解这个问题,但由于我有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;
}
我认为你的代码设计过度了。我对它进行了重构,并简化了它,如图所示。如果你真的想要一个沉重的OOP设置,我建议你使用客户端MVC (Backbone, knockout等)结构来正确地完成它,或者保持它的轻量。
我将继续对您的代码进行一般反馈。
/* 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();
}
没有理由像这样使用单例。使用.__proto__
我推荐这样的样式。
var Stream = (function() {
var Stream = function() { ... };
// prototype stuff
var stream = new Stream();
return function() {
return stream;
};
})());
在原型上存储这样的数据散列是不必要的。
Stream.prototype.selectors = {
stream : '#stream',
post_content : '#post-content',
add_post: '#add-post',
// ... more action selectors
}
你可以把它作为默认的哈希值。
(function() {
var defaults = {
stream : '#stream',
post_content : '#post-content',
add_post: '#add-post',
// ... more action selectors
}
function Stream() {
...
this.elements = jQueryMapping(defaults);
}
}());
你的效用函数可以稍微优化一下。
$map[key] = (context) ? $(value, context) : $(value);
可以重写为
$map[key] = $(value, context)
因为如果context
是未定义的,你只是传递一个未定义的参数,这与不传递参数相同。
这篇文章的标题是"初学者",但是我发现这一节是关于设计模式的,这一节是关于使用jQuery设计模式的。
相关文章:
- 在Web应用程序中使用Highcharts javascript
- 将下载链接从web浏览器传递给第三方应用程序
- 在web应用程序中的新搜索中重新加载搜索结果(不带jQuery)
- Web应用程序,将成员状态更新为其他成员
- 同一文本框中的验证程序CPF e CNPJ(ASP.NET web应用程序)
- web浏览器中的离线应用程序存储数据并在之后上传
- 使用Ember的Web应用程序架构.动画逻辑应该放在哪里
- 如何使用默认的网络摄像头拍摄照片并将其保存在我的c#.net web应用程序中
- c#web应用程序中的条形码打印
- 使用javascript为web应用程序自定义键盘快捷键
- 使用angularjs和node.js时的Web应用程序文件夹结构
- PhpWindows 8.1版本上的Javascript web应用程序
- 是否有任何开源web应用程序具有良好的QUnit(或JSUnit)测试用例
- Project和作为web应用程序发布的多个doGet()脚本文件——需要澄清
- 无法在Windows 10 Cordova应用程序中从Web视图进行ajax调用
- 如何获取使用我们的脚本或web应用程序的网站名称
- 没有框架/DLL的VS Web应用程序项目
- 正确传输和保护用户'web应用程序的密码
- 检查Progressive web应用程序中的网络更改
- 如何在应用程序>Web浏览器控件中使用Google Maps API v3 ClientID