Knockout : 实现复杂的web聊天窗体
公司以前一个同事写的这个聊天的窗体,由于是采用了html拼接的方式,外加处理的时候没有合理的划分职责,导致页面js代码量非常庞大(1500行左右)。现在这哥们离职了,苦的是我们剩下的人,不多说,我先去擦把泪。
公司基本没周都要求给web聊天加各种各样的功能,然后各种不能忍,权衡之后只能选择重构代码,可怜的娃娃啊。。。。
本次完全采用Knockout重构,基础的东西就不多说了,学习Knockout请移步大叔的blog(多谢大叔无私分享) http://www.cnblogs.com/TomXu/archive/2011/11/21/2257154.html
上web聊天界面截图:

view代码:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>后台聊天</title>
<link rel="stylesheet" href="css/jquery.qqFace-min.css" />
<link rel="stylesheet" href="css/index0923.css" />
<style type="text/css">
/* style="display:none;" */
</style>
</head> <body>
<div class="chatDiv" id="chatDiv" style="border:1px solid #ededed;">
<!-- 单聊 -->
<div id="singleChat">
<!-- 聊天联系人列表 -->
<div class="chatLp">
<!--div class="title"><a href="###" class="clearAll">清空</a></div-->
<div class="title">
<a href="###" class="sendAll l">群发</a>
<a href="javascript:void(0);" class="delete r" data-bind="click:function(){viewModel.clearArray();}"></a>
</div>
<ul class="chatList" data-bind="template:{ name: 'demo',foreach:viewModel.viewModelArray}">
<!--<li><i class="ico icoOne"></i><i class="come"></i><span class="txt">八卦台湾</span></li>
<li class="select"><i class="ico icoOne"></i><span class="txt">八卦台湾</span></li>
<li><img class="ico" src="data:images/img.png"/><span class="txt">八卦台湾</span></li>--> </ul>
</div>
<div class="chatRp">
<div class="chatName" data-bind="template:{ name: 'title',foreach:viewModel.selectViewModel}"> </div>
<!-- 对话内容 -->
<div class="content">
<div id="chatMain" class="chatMain" style="overflow-y: scroll;" tabindex="5001" data-bind="template:{ name: 'content',foreach:viewModel.selectModel}"> </div>
<div class="speakInp">
<span class="spaeakBtn biaoq"></span>
<span class="spaeakBtn edit"></span>
<textarea class="textarea-txt" style="overflow: hidden;" data-bind="value:textContent"></textarea>
<a class="sub_btn" href="javascript:void(0);" data-bind="click:function(){viewModel.msgPush();}">发送</a>
</div>
</div>
</div>
<div class="clearB"></div>
</div>
</div>
<div>
<button data-bind="click:add">Add</button>
</div>
<script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="js/jquery.qqFace-min.js"></script>
<script type="text/javascript" src="js/jquery.nicescroll.min.js"></script>
<script src="js/jquery.tmpl.js"></script>
<script src="js/knockout-2.0.0.debug.js"></script>
<script type="text/x-jquery-tmpl" id="demo"> <li data-bind="click:function() {viewModel.select($data)},css:{select:$data.data()==viewModel.selectModel()},
event: { mouseover:function(){ viewModel.showCloseIco($data,true);}, mouseout: function(){ viewModel.showCloseIco($data,false);} }"> <img class="ico" data-bind="css:{icoOne:$data.data().length>0}" src="${ico}"></img>
<span class="txt">${name}</span>
<i class="icodelete" data-bind="click:function () {viewModel.remove($data)},style:{display:$data.isShow()== true?'inline':'none'}"></i>
</li> </script> <script type="text/x-jquery-tmpl" id="content">
<div class="anotherIetm" data-bind="css:{selfIetm:$data.msgtype }">
<div class="icoP"><img src="${ico}" class="ico"></div>
<div class="contentP">
<span class="name">${name}</span>
<div class="speakCon">
<span class="jiao"></span>
<div class="mainCont">${msg}</div>
<div class="clearB"></div>
</div>
</div>
<div class="clearB"></div>
</div>
</script> <script type="text/x-jquery-tmpl" id="title">
<span class="left">${name}</span>
<span class="right">
<span>您的身份:[${serverId}]</span>
</span>
<div class="clearB"></div>
</script> <script src="ChatModel.js"></script>
<script src="ChatViewModel.js"></script>
</body>
</html>
Model代码:
/// <reference path="js/knockout-2.0.0.debug.js" />
function LeftObject(ico, name, serverid) {
this.ico = ico;
this.name = name;
this.isShow = ko.observable();
this.data = ko.observableArray();
this.serverId = serverid;
} function MsgContent(msgtype, msg, name, ico) {
this.msgtype = msgtype;
this.msg = msg;
this.name = name;
this.ico = ico;
}
ViewModel代码:
/// <reference path="js/knockout-2.0.0.debug.js" />
//======================左边用户列表操作===========================
var num = 0;
var viewModel = {
add: function () {
num = num + 1;
viewModel.viewModelArray.push(new LeftObject("http://www.baidu.com/img/bdlogo.png", "Test" + num,"客服-应用主"));
if (viewModel.selectModel().length == 0) {
viewModel.selectModel(viewModel.viewModelArray()[viewModel.viewModelArray().length - 1].data());
viewModel.selectViewModel(viewModel.viewModelArray()[viewModel.viewModelArray().length - 1]);
}
},
push: function () {
if (viewModel.selectModel()) {
viewModel.selectModel.push({ content: num, isSend: (num % 2 == 1) })
}
},
viewModelArray: ko.observableArray()
};
viewModel.remove = function (e) {
viewModel.viewModelArray.remove(e); if (viewModel.selectModel() == e.data()) {
viewModel.selectModel([]);
}
viewModel.selectModel(viewModel.viewModelArray()[0].data());
viewModel.selectViewModel(viewModel.viewModelArray()[0]);
}
viewModel.select = function (e) {
viewModel.selectModel(e.data());
viewModel.selectViewModel(e);
}
viewModel.selectModel = ko.observableArray();
viewModel.selectViewModel = ko.observable(); viewModel.showCloseIco = function (e,isShow) {
e.isShow(isShow);
//alert(e.isShow());
} viewModel.clearArray = function () {
viewModel.viewModelArray([]);
} //===========================分割线 下面是聊天窗口操作函数=========================================== viewModel.msgAccept = function (data) {
viewModel.selectModel.push(new MsgContent(true, data, "自己", "images/ico.png"));
} viewModel.msgSend = function (data) {
viewModel.selectModel.push(new MsgContent(false, data, "别人", "images/img.png"));
}
viewModel.textContent = ko.observable();
//模拟发送
viewModel.msgPush = function (data) { if (viewModel.viewModelArray().length == 0) {
return;
}
var d = parseInt( Math.random()*10 % 2);
data = viewModel.textContent();
viewModel.textContent('');
if (d == 0) {
viewModel.msgSend(data);
} else {
viewModel.msgAccept(data);
}
} //=====================================================================
ko.applyBindings(viewModel);
Knockout : 实现复杂的web聊天窗体的更多相关文章
- 高仿webqq做的一个webos桌面效果和web聊天工具,桌面效果完好,功能强大
QQ技术交流群:159995692 /-------- 暂时开放的測试 帐号/password:[88888888/1;666666/1] ---------/ 正如大家所知的E ...
- 使用Servlet和JSP实现一个简单的Web聊天室系统
1 问题描述 利用Java EE相关技术实现一个简单的Web聊天室系统,具体要求如下. (1)编写一个登录 ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室 实战系列
ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(零) 前言 http://www.cnblogs.com/panzi/p/5742089.html ASP.NET S ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(十二) 代码重构使用反射工厂解耦(一)缓存切换
前言 上一篇中,我们用了反射工厂来解除BLL和UI层耦合的问题.当然那是最简单的解决方法,再复杂一点的程序可能思路相同,但是在编程细节中需要考虑的就更多了,比如今天我在重构过程中遇到的问题.也是接下来 ...
- web聊天室
开发一个web聊天室 功能需求: 1.用户可以与好友一对一聊天 2.群聊 所需知识 1.Django 2.bootstrap 3.CSS 4.ajax 涉及到的新的知识点 1.如果设计表结构的时候,一 ...
- 利用html 5 websocket做个山寨版web聊天室(手写C#服务器)
在之前的博客中提到过看到html5 的websocket后很感兴趣,终于可以摆脱长轮询(websocket之前的实现方式可以看看Developer Works上的一篇文章,有简单提到,同时也说了web ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(零) 前言
前端时间听一个技术朋友说 LayIM 2.0 发布了,听到这个消息抓紧去官网看了一下.(http://layim.layui.com/)哎呀呀,还要购买授权[大家支持一下哦],果断买了企业版,喜欢钻研 ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(一) 之 基层数据搭建,让数据活起来(数据获取)
大家好,本篇是接上一篇 ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(零) 前言 ASP.NET SignalR WebIM系列第二篇.本篇会带领大家将 LayIM ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(二) 之 ChatServer搭建,连接服务器,以及注意事项。
上篇:ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(一) 之 基层数据搭建,让数据活起来(数据获取) 上一篇我们已经完成了初步界面的搭建工作,本篇将介绍IM的核心内容 ...
随机推荐
- java.lang.IllegalArgumentException
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.Persiste ...
- 洛谷P1268 树的重量
P1268 树的重量 85通过 141提交 题目提供者该用户不存在 标签树形结构 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 有这种情况吗!!!! 题意似乎有问题 题目描述 树可以用来表 ...
- 25_android下文件访问的权限
写文件:FileOutputStream fos = 上下文.openFileOutput("private.txt",Context.MODE_PRIVATR);参数1 文件名, ...
- ASP.NET运行机制原理 ---浏览器与IIS的交互过程 自己学习 网上查了下别人写的总结的很好 就转过来了 和自己写的还好里嘻嘻
一.浏览器和服务器的交互原理 (一).浏览器和服务器交互的简单描述: 1.通俗描述:我们平时通过浏览器来访问网站,其实就相当于你通过浏览器去访问一台电脑上访问文件一样,只不过浏览器的访问请求是由被访问 ...
- [转载]:Endnote 自定义style文件的默认位置
一般而言,安裝完EndNote 後,預設Output Styles.Filters.Connection Files 的電腦存放路徑如下– C:\Program Files\EndNote X4 ...
- Windows Phone开发(12):认识一下独具个性的磁贴(转)
对"磁贴"的理解是一点也不抽象的,为什么呢?只要你愿意启动WP系统,无论你是在模拟器中还是在真机中,是的,桌面上那一块块像地板的玩意儿,就是磁贴了.(图:磁贴) 在上图中,我们很直 ...
- linux 内核(驱动)常用函数
2.4.1 内存申请和释放 include/linux/kernel.h里声明了kmalloc()和kfree().用于在内核模式下申请和释放内存. void *kmalloc(unsigned ...
- LESS 拓展选择器extend基础用法说明
扩展选择器是less的伪类选择器,他会复制当前选择器,定义新的样式,而原来的不变 nav ul { &:extend(.inline); background: blue; } .inline ...
- ASP.NET 项目 App_Code下无法找到类
APP_CODE 默认情况下,VS2010中新建的WebApplication中是没有App_Code文件夹的,若需要使用,可以自己手动添加文件夹,然后将文件夹名称设置为App_Code,然后在该文件 ...
- mysql快速上手1
mysql简介 1.什么是数据库 ? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,它产生于距今六十多年前,随着信息技术和市场的发展,特别是二十世纪九十年代以后,数据管理不再仅 ...