Backbone实例todos分析
源码来自:http://todomvc.com/examples/backbone/
这是一个用Backbone.js完成的待办事项实例,精简但完善,可以帮助很好的帮助理解Backbone的API,MVC框架和写webApp的基本思路。
下面让我们一步步分析,
准备工作:
首先是html页面,新建index.html,并保存以下代码:
<!doctype html>
<html lang="en" data-framework="backbonejs">
<head>
<meta charset="utf-8">
<title>Backbone.js • TodoMVC</title>
<link rel="stylesheet" href="bower_components/todomvc-common/base.css">
</head>
<body>
<section id="todoapp">
<header id="header">
<h1>todos</h1>
<input id="new-todo" placeholder="What needs to be done?" autofocus>
</header>
<section id="main">
<input id="toggle-all" type="checkbox">
<label for="toggle-all">Mark all as complete</label>
<ul id="todo-list"></ul>
</section>
<footer id="footer"></footer>
</section>
<footer id="info">
<p>Double-click to edit a todo</p>
<p>Written by <a href="https://github.com/addyosmani">Addy Osmani</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer>
<!-- Templates -->
<script type="text/template" id="item-template">
<div class="view">
<input class="toggle" type="checkbox" <%= completed ? 'checked' : '' %>>
<label><%- title %></label>
<button class="destroy"></button>
</div>
<input class="edit" value="<%- title %>">
</script>
<script type="text/template" id="stats-template">
<span id="todo-count"><strong><%= remaining %></strong> <%= remaining === 1 ? 'item' : 'items' %> left</span>
<ul id="filters">
<li>
<a class="selected" href="#/">All</a>
</li>
<li>
<a href="#/active">Active</a>
</li>
<li>
<a href="#/completed">Completed</a>
</li>
</ul>
<% if (completed) { %>
<button id="clear-completed">Clear completed (<%= completed %>)</button>
<% } %>
</script>
<script src="bower_components/jquery/jquery.js"></script>
<script src="bower_components/underscore/underscore.js"></script>
<script src="bower_components/backbone/backbone.js"></script>
<script src="bower_components/backbone.localStorage/backbone.localStorage.js"></script>
<script src="js/models/todo.js"></script>
<script src="js/collections/todos.js"></script>
<script src="js/views/todo-view.js"></script>
<script src="js/views/app-view.js"></script>
<script src="js/routers/router.js"></script>
<script src="js/app.js"></script>
</body>
</html>
这是webapp的主页面,它引入的文件有样式表base.css;js框架jquery.js,underscore.js,backbone.js,backbone.localStorage.js,请大家自行引入。然后是即将利用backbone编写的js代码.为了方便理解,原作者将这些JS代码分成了5个JS文件,我们将深入分析。
先简单介绍一下这些js框架和我们页面的关系:
1.jquery.js:我们将利用jquery操作dom,
2.underscore.js:backbone的依赖库,提供一下方便的方法,和模板的操作。
3.backbone.js:我们主要使用的MVC框架
4.backbone.localStorage.js:backbone的拓展库,用来操作HTML5新加入的本地存储
页面的样式表base.css
html,
body {
margin:;
padding:;
} button {
margin:;
padding:;
border:;
background: none;
font-size: 100%;
vertical-align: baseline;
font-family: inherit;
color: inherit;
-webkit-appearance: none;
-ms-appearance: none;
-o-appearance: none;
appearance: none;
} body {
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
line-height: 1.4em;
background: #eaeaea url('bg.png');
color: #4d4d4d;
width: 550px;
margin: 0 auto;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased;
} button,
input[type="checkbox"] {
outline: none;
} #todoapp {
background: #fff;
background: rgba(255, 255, 255, 0.9);
margin: 130px 0 40px 0;
border: 1px solid #ccc;
position: relative;
border-top-left-radius: 2px;
border-top-right-radius: 2px;
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2),
0 25px 50px 0 rgba(0, 0, 0, 0.15);
} #todoapp:before {
content: '';
border-left: 1px solid #f5d6d6;
border-right: 1px solid #f5d6d6;
width: 2px;
position: absolute;
top:;
left: 40px;
height: 100%;
} #todoapp input::-webkit-input-placeholder {
font-style: italic;
} #todoapp input::-moz-placeholder {
font-style: italic;
color: #a9a9a9;
} #todoapp h1 {
position: absolute;
top: -120px;
width: 100%;
font-size: 70px;
font-weight: bold;
text-align: center;
color: #b3b3b3;
color: rgba(255, 255, 255, 0.3);
text-shadow: -1px -1px rgba(0, 0, 0, 0.2);
-webkit-text-rendering: optimizeLegibility;
-moz-text-rendering: optimizeLegibility;
-ms-text-rendering: optimizeLegibility;
-o-text-rendering: optimizeLegibility;
text-rendering: optimizeLegibility;
} #header {
padding-top: 15px;
border-radius: inherit;
} #header:before {
content: '';
position: absolute;
top:;
right:;
left:;
height: 15px;
z-index:;
border-bottom: 1px solid #6c615c;
background: #8d7d77;
background: -webkit-gradient(linear, left top, left bottom, from(rgba(132, 110, 100, 0.8)),to(rgba(101, 84, 76, 0.8)));
background: -webkit-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');
border-top-left-radius: 1px;
border-top-right-radius: 1px;
} #new-todo,
.edit {
position: relative;
margin:;
width: 100%;
font-size: 24px;
font-family: inherit;
line-height: 1.4em;
border:;
outline: none;
color: inherit;
padding: 6px;
border: 1px solid #999;
box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased;
} #new-todo {
padding: 16px 16px 16px 60px;
border: none;
background: rgba(0, 0, 0, 0.02);
z-index:;
box-shadow: none;
} #main {
position: relative;
z-index:;
border-top: 1px dotted #adadad;
} label[for='toggle-all'] {
display: none;
} #toggle-all {
position: absolute;
top: -42px;
left: -4px;
width: 40px;
text-align: center;
/* Mobile Safari */
border: none;
} #toggle-all:before {
content: '»';
font-size: 28px;
color: #d9d9d9;
padding: 0 25px 7px;
} #toggle-all:checked:before {
color: #737373;
} #todo-list {
margin:;
padding:;
list-style: none;
} #todo-list li {
position: relative;
font-size: 24px;
border-bottom: 1px dotted #ccc;
} #todo-list li:last-child {
border-bottom: none;
} #todo-list li.editing {
border-bottom: none;
padding:;
} #todo-list li.editing .edit {
display: block;
width: 506px;
padding: 13px 17px 12px 17px;
margin: 0 0 0 43px;
} #todo-list li.editing .view {
display: none;
} #todo-list li .toggle {
text-align: center;
width: 40px;
/* auto, since non-WebKit browsers doesn't support input styling */
height: auto;
position: absolute;
top:;
bottom:;
margin: auto 0;
/* Mobile Safari */
border: none;
-webkit-appearance: none;
-ms-appearance: none;
-o-appearance: none;
appearance: none;
} #todo-list li .toggle:after {
content: '✔';
/* 40 + a couple of pixels visual adjustment */
line-height: 43px;
font-size: 20px;
color: #d9d9d9;
text-shadow: 0 -1px 0 #bfbfbf;
} #todo-list li .toggle:checked:after {
color: #85ada7;
text-shadow: 0 1px 0 #669991;
bottom: 1px;
position: relative;
} #todo-list li label {
white-space: pre;
word-break: break-word;
padding: 15px 60px 15px 15px;
margin-left: 45px;
display: block;
line-height: 1.2;
-webkit-transition: color 0.4s;
transition: color 0.4s;
} #todo-list li.completed label {
color: #a9a9a9;
text-decoration: line-through;
} #todo-list li .destroy {
display: none;
position: absolute;
top:;
right: 10px;
bottom:;
width: 40px;
height: 40px;
margin: auto 0;
font-size: 22px;
color: #a88a8a;
-webkit-transition: all 0.2s;
transition: all 0.2s;
} #todo-list li .destroy:hover {
text-shadow: 0 0 1px #000,
0 0 10px rgba(199, 107, 107, 0.8);
-webkit-transform: scale(1.3);
transform: scale(1.3);
} #todo-list li .destroy:after {
content: '✖';
} #todo-list li:hover .destroy {
display: block;
} #todo-list li .edit {
display: none;
} #todo-list li.editing:last-child {
margin-bottom: -1px;
} #footer {
color: #777;
padding: 0 15px;
position: absolute;
right:;
bottom: -31px;
left:;
height: 20px;
z-index:;
text-align: center;
} #footer:before {
content: '';
position: absolute;
right:;
bottom: 31px;
left:;
height: 50px;
z-index: -1;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3),
0 6px 0 -3px rgba(255, 255, 255, 0.8),
0 7px 1px -3px rgba(0, 0, 0, 0.3),
0 43px 0 -6px rgba(255, 255, 255, 0.8),
0 44px 2px -6px rgba(0, 0, 0, 0.2);
} #todo-count {
float: left;
text-align: left;
} #filters {
margin:;
padding:;
list-style: none;
position: absolute;
right:;
left:;
} #filters li {
display: inline;
} #filters li a {
color: #83756f;
margin: 2px;
text-decoration: none;
} #filters li a.selected {
font-weight: bold;
} #clear-completed {
float: right;
position: relative;
line-height: 20px;
text-decoration: none;
background: rgba(0, 0, 0, 0.1);
font-size: 11px;
padding: 0 10px;
border-radius: 3px;
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2);
} #clear-completed:hover {
background: rgba(0, 0, 0, 0.15);
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.3);
} #info {
margin: 65px auto 0;
color: #a6a6a6;
font-size: 12px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
text-align: center;
} #info a {
color: inherit;
} /*
Hack to remove background from Mobile Safari.
Can't use it globally since it destroys checkboxes in Firefox and Opera
*/ @media screen and (-webkit-min-device-pixel-ratio:0) {
#toggle-all,
#todo-list li .toggle {
background: none;
} #todo-list li .toggle {
height: 40px;
} #toggle-all {
top: -56px;
left: -15px;
width: 65px;
height: 41px;
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
-webkit-appearance: none;
appearance: none;
}
} .hidden {
display: none;
} hr {
margin: 20px 0;
border:;
border-top: 1px dashed #C5C5C5;
border-bottom: 1px dashed #F7F7F7;
} .learn a {
font-weight: normal;
text-decoration: none;
color: #b83f45;
} .learn a:hover {
text-decoration: underline;
color: #787e7e;
} .learn h3,
.learn h4,
.learn h5 {
margin: 10px 0;
font-weight:;
line-height: 1.2;
color: #000;
} .learn h3 {
font-size: 24px;
} .learn h4 {
font-size: 18px;
} .learn h5 {
margin-bottom:;
font-size: 14px;
} .learn ul {
padding:;
margin: 0 0 30px 25px;
} .learn li {
line-height: 20px;
} .learn p {
font-size: 15px;
font-weight:;
line-height: 1.3;
margin-top:;
margin-bottom:;
} .quote {
border: none;
margin: 20px 0 60px 0;
} .quote p {
font-style: italic;
} .quote p:before {
content: '“';
font-size: 50px;
opacity: .15;
position: absolute;
top: -20px;
left: 3px;
} .quote p:after {
content: '”';
font-size: 50px;
opacity: .15;
position: absolute;
bottom: -42px;
right: 3px;
} .quote footer {
position: absolute;
bottom: -40px;
right:;
} .quote footer img {
border-radius: 3px;
} .quote footer a {
margin-left: 5px;
vertical-align: middle;
} .speech-bubble {
position: relative;
padding: 10px;
background: rgba(0, 0, 0, .04);
border-radius: 5px;
} .speech-bubble:after {
content: '';
position: absolute;
top: 100%;
right: 30px;
border: 13px solid transparent;
border-top-color: rgba(0, 0, 0, .04);
} .learn-bar > .learn {
position: absolute;
width: 272px;
top: 8px;
left: -300px;
padding: 10px;
border-radius: 5px;
background-color: rgba(255, 255, 255, .6);
-webkit-transition-property: left;
transition-property: left;
-webkit-transition-duration: 500ms;
transition-duration: 500ms;
} @media (min-width: 899px) {
.learn-bar {
width: auto;
margin: 0 0 0 300px;
} .learn-bar > .learn {
left: 8px;
} .learn-bar #todoapp {
width: 550px;
margin: 130px auto 40px auto;
}
}
代码分析:
todo.js
//app对象
var app = app || {}; (function () {
'use strict'; // Todo 模型
// ---------- //我们基本的Todo模型有`title`,`order`,`completed`,属性
app.Todo = Backbone.Model.extend({
//todo默认属性,确保每个对象都拥有`title` and `completed`.
defaults: {
title: '',
completed: false
}, //改变todo中`completed`属性为反向状态
toggle: function () {
this.save({
completed: !this.get('completed')
});
}
});
})();
在todo app我们实现要实现的功能中,一个基本待办事项就是最基本的数据模型,它拥有title,completed,order,三个属性,分别表示显示的标题,是否完成和顺序,其中title,completed为默认属性。
模型有一个改变状态的方法。save方法除了将数据保存到模型中,还将向服务器发送request请求,如果成功,触发sync事件。简言之,与数据存储方面配合,利用save不单是将数据存储到我们定义的模型里,还将保存到服务器上。
todos.js
//app对象
var app = app || {}; (function () {
'use strict'; // Todo 集合
// --------------- // 这里数据集合将存储到本地存储,替代服务器存储
var Todos = Backbone.Collection.extend({
//引用这个集合的模型
model: app.Todo, // 集合中所有的todo 模型都将存在本地
localStorage: new Backbone.LocalStorage('todos-backbone'), // 过滤为所有完成的todo模型
completed: function () {
return this.where({completed: true});
}, // 过滤为所有为完成的todo模型
remaining: function () {
return this.where({completed: false});
}, // 我们将保持Todos有序,不管是不是被无序存储
// 生成下个todo模型的顺序ID
nextOrder: function () {
return this.length ? this.last().get('order') + 1 : 1;
}, // 所有的todo将以最初插入的顺序保存到Todos当中。
comparator: 'order'
}); // 创建一个todos集合。
app.todos = new Todos();
})();
这是数据模型的集合。
todo-view.js
var app = app || {}; (function ($) {
'use strict'; // todo 单个模型的视图
// -------------- // 一个todo模型的DOM元素
app.TodoView = Backbone.View.extend({
// 整个视图在一个li标签中
tagName: 'li', // 缓存单个模型的模板函数
template: _.template($('#item-template').html()), // 定义单个模型页面视图中指定DOM元素触发事件时调用的函数
events: {
'click .toggle': 'toggleCompleted',
'dblclick label': 'edit',
'click .destroy': 'clear',
'keypress .edit': 'updateOnEnter',
'keydown .edit': 'revertOnEscape',
'blur .edit': 'close'
}, // 监听其对应模型的事件,这是一对一的,这个视图,监听其模型。
initialize: function () {
this.listenTo(this.model, 'change', this.render);
this.listenTo(this.model, 'destroy', this.remove);
this.listenTo(this.model, 'visible', this.toggleVisible);
}, // 生成模型的标题。
render: function () {
//Backbone LocalStorage保存模型时,会增加一个ID属性,这将引起render事件再次发生。我们想过滤由此引起的第二次render,因此增加了一段功能。
// 这是localStorage.js的一个BUG,相关信息可以查看 https://github.com/tastejs/todomvc/issues/469
if (this.model.changed.id !== undefined) {
return;
} this.$el.html(this.template(this.model.toJSON()));
this.$el.toggleClass('completed', this.model.get('completed'));
this.toggleVisible();
this.$input = this.$('.edit');
return this;
}, toggleVisible: function () {
this.$el.toggleClass('hidden', this.isHidden());
}, isHidden: function () {
return this.model.get('completed') ?
app.TodoFilter === 'active' :
app.TodoFilter === 'completed';
}, // 改变模型completed状态
toggleCompleted: function () {
this.model.toggle();
}, // 转到编辑状态
edit: function () {
this.$el.addClass('editing');
this.$input.focus();
}, // 关闭编辑模式,存储对模型的改变
close: function () {
var value = this.$input.val();
var trimmedValue = value.trim(); // 在非编辑状态下直接返回
if (!this.$el.hasClass('editing')) {
return;
} if (trimmedValue) {
this.model.save({ title: trimmedValue }); if (value !== trimmedValue) {
// 只增加了两边的空格的更改并不会存入服务器中,在此情况下,我们重新渲染视图,
// 达到显示和后台统一的目的。
this.model.trigger('change');
}
} else {
this.clear();
} this.$el.removeClass('editing');
}, // 如果你按下回车键,将跳到编辑状态
updateOnEnter: function (e) {
if (e.which === ENTER_KEY) {
this.close();
}
}, // 如果你按下esc键,将恢复视图为模型的数据,并离开编辑状态
revertOnEscape: function (e) {
if (e.which === ESC_KEY) {
this.$el.removeClass('editing');
// 重置输入框为模型中的数据
this.$input.val(this.model.get('title'));
}
}, // 删除条目,并从localStorage中销毁,并删除视图(事件监听destroy)
clear: function () {
this.model.destroy();
}
});
})(jQuery);
这里是单个条目的视图,它主要负责对单个条目的操作,如删除,更改等每个条目都有的功能。
app-view.js
var app = app || {}; (function ($) {
'use strict'; // 程序
// --------------- // 整体的程序视图
app.AppView = Backbone.View.extend({ // 视图绑定为已经存在的页面节点
el: '#todoapp', // 缓存状态模板
statsTemplate: _.template($('#stats-template').html()), events: {
'keypress #new-todo': 'createOnEnter',
'click #clear-completed': 'clearCompleted',
'click #toggle-all': 'toggleAllComplete'
}, // 在初始化时,我们绑定相关的事件到集合实例上,
// 重置时,重新添加所有模型。
initialize: function () {
this.allCheckbox = this.$('#toggle-all')[0];
this.$input = this.$('#new-todo');
this.$footer = this.$('#footer');
this.$main = this.$('#main');
this.$list = $('#todo-list'); this.listenTo(app.todos, 'add', this.addOne);
this.listenTo(app.todos, 'reset', this.addAll);
this.listenTo(app.todos, 'change:completed', this.filterOne);
this.listenTo(app.todos, 'filter', this.filterAll);
this.listenTo(app.todos, 'all', this.render); // 抑制由于每个add事件引起的视图生成。从本地存储获取到模型时,触发reset事件,添加所有的模型到集合中。
app.todos.fetch({reset: true});
}, // reset并不会引起视图的生成。
render: function () {
var completed = app.todos.completed().length;
var remaining = app.todos.remaining().length; if (app.todos.length) {
this.$main.show();
this.$footer.show(); this.$footer.html(this.statsTemplate({
completed: completed,
remaining: remaining
})); this.$('#filters li a')
.removeClass('selected')
.filter('[href="#/' + (app.TodoFilter || '') + '"]')
.addClass('selected');
} else {
this.$main.hide();
this.$footer.hide();
} this.allCheckbox.checked = !remaining;
}, // 为新增的模型创建视图,添加到页面中去
addOne: function (todo) {
var view = new app.TodoView({ model: todo });
this.$list.append(view.render().el);
}, // 一次添加所有模型视图
addAll: function () {
this.$list.html('');
app.todos.each(this.addOne, this);
}, filterOne: function (todo) {
todo.trigger('visible');
}, filterAll: function () {
app.todos.each(this.filterOne, this);
}, // 生成新模型的属性
newAttributes: function () {
return {
title: this.$input.val().trim(),
order: app.todos.nextOrder(),
completed: false
};
}, // 回车键保存模型,且保存到localStorage
createOnEnter: function (e) {
if (e.which === ENTER_KEY && this.$input.val().trim()) {
app.todos.create(this.newAttributes());
this.$input.val('');
}
}, // 清除所有完成的模型,
clearCompleted: function () {
_.invoke(app.todos.completed(), 'destroy');
return false;
}, toggleAllComplete: function () {
var completed = this.allCheckbox.checked; app.todos.each(function (todo) {
todo.save({
completed: completed
});
});
}
});
})(jQuery);
主视图,主程序,前面所有的模型,集合,视图,都由他来管理。渲染整个视图,监听新增事件,添加条目到集合中等全面的问题处理。
route.js
var app = app || {}; (function () {
'use strict'; // Todo 路由
// ----------
var TodoRouter = Backbone.Router.extend({
routes: {
'*filter': 'setFilter'
}, setFilter: function (param) {
// 存储目前的过滤参数。
app.TodoFilter = param || ''; // 触发过滤事件,改变视图的隐藏显示。
app.todos.trigger('filter');
}
}); app.TodoRouter = new TodoRouter();
Backbone.history.start();
})();
利用route,保存参数到变量中,供程序使用
app.js
var app = app || {};
var ENTER_KEY = 13;
var ESC_KEY = 27; $(function () {
'use strict'; // 创建App实例,初始化所有功能
new app.AppView();
});
初始化真个程序。
Backbone实例todos分析的更多相关文章
- Backbone源码分析(三)
Backbone源码分析(一) Backbone源码分析(二) Backbone中主要的业务逻辑位于Model和Collection,上一篇介绍了Backbone中的Model,这篇文章中将主要探讨C ...
- backbone实例01
backbonejs往简单说,就是一前端MVC框架,适合用于单页面.复杂的前端逻辑. 直接上代码,里面都有相关注释,重点是理解清楚view.collection.model这三者如何关联调用. < ...
- php数组去重实例及分析
php数组去重实例及分析. 一维数组的重复项: 使用array_unique函数即可,使用实例 <?php $aa=array("apple","banan ...
- 通过实例来分析I2C基本通信协议
本文旨在用最通俗易懂的方式.让大家明确I2C通信的过程到底是怎么回事. I2C起源于飞利浦公司的电视设计,但之后朝通用路线发展,各种电子设计都有机会用到I2C 总的来说,I2C能够简单归纳为,两根线, ...
- 有关RDS上只读实例延时分析-同适用于自建MySQL主从延时分析判断
个人不是很喜欢在技术上跟人互喷,尤其是不在同一个岗位上的人.一方面本人的性格如此,另一方面,我自身的口水也确实是不行,人生经历了第一次的双11洗礼,在大促的环境下,总算知道了有些东西是否应该规避,这次 ...
- Backbone源码分析-Backbone架构+流程图
作者:nuysoft/高云/nuysoft@gmail.com 声明:本文为原创文章,如需转载,请注明来源并保留原文链接. Backbone0.9.1源码分析分析系列 jQuery1.6.1源码分析系 ...
- Hello2实例的分析
首先: java EE 上的hello2项目是一个部署在glass fish上的开发源码的java web项目,在终端通过命令行使用maven进行打包成.war文件,最后部署到相关的glass fis ...
- Netty入门实例及分析
什么是netty?以下是官方文档的简单介绍: The Netty project is an effort to provide an asynchronous event-driven netwo ...
- SQLServer数据库,表内存,实例名分析SQL语句
--数据库内存分析 USE master go DECLARE @insSize TABLE(dbName sysname,checkTime VARCHAR(19),dbSize VARCHAR(5 ...
随机推荐
- #include <boost/unordered_set.hpp>
boost.unordered在C++标准容器std::set,std::multiset,std::map和std::multimap的基础上多实现了四个容器:boost::unordered_se ...
- cf公式专场-续
Benches Time Limit:500MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Statu ...
- JAVA Socket连接服务器时可能抛出的异常
1.UnknownHostException:host(非ip)无法识,就会报该异常,www.google.com.hk这个虽然也ping不通,但是不会报该错,因为他是一个确实存在的域名.他会报Con ...
- .net通用权限框架B/S(一)
一直做软件实施,用过一些二次开发平台,最近看了一些大神写的框架,于是参考写了一个B/S通用权限框架,项目使用MVC4+EF5+EASYUI(.net framework4),开发环境vs2010+sq ...
- Spring事务传播机制详解
1 事务的传播属性(Propagation) 1) REQUIRED ,这个是默认的属性 Support a current transaction, create a new one if none ...
- 安装oneproxy实现数据库的读写分离
领导就给了两台数据库,做主从,在从上搭建oneproxy插件,实现读写分离,一直就听说oneproxy,今天打算用一下 先下载最新的版本wget http://www.onexsoft.cn/soft ...
- 看懂此文,不再困惑于 JS 中的事件设计
看懂此文,不再困惑于 JS 中的事件设计 今天刚在关注的微信公众号看到的文章,关于JS事件的,写的很详细也很容易理解,相关的知识点都有总结到,看完就有种很舒畅的感觉,该串起来的知识点都串起来了.反正一 ...
- 在windows平台下忘记了root的密码如何解决?
1.打开MySQL配置文件 my.ini中,添加上skip-grant-tables,可以添加到文件的末尾或者是这添加到[mysqld]的下面. 2.然后重启MYSQL服务 windows环境中: n ...
- Sublime text3 安装和配置
1.下载安装 首先到http://www.sublimetext.com/3根据你的电脑配置下载对应的安装包,然后不断的点击next,然后blablabla......就可以安装好了.本文是安装por ...
- python 自学笔记(四) 列表
有几天没有更新博客了,毕竟是自学,最近事情确实比较多,有时候想学的时候反而没时间,到有时间的时候反而不想学.以后得想办法改掉这个缺点,只要有时间就要学习自己想学的东西,希望自学的同学能和我共同交流,其 ...