Introduction
brick是一个轻量级前端开发框架,基于jQuery和underscore。主要用于提升前端页面开发效率及复杂功能页面js代码的组织性和维护性。 其设计及实现主要借鉴并且反映了angular的前端开发思想及解决方案。
其主要思想包含几点:
1. 对代码类型进行划分,隔离。 因为前端开发通常同时涉及html、css、js,通过对代码类型进行划分,以提高代码复用性及维护性。 通常分为以下几种类型的代码:
* ctrl(控制器)类型代码,主要用于衔接dom操作及service调用。
* service(服务)类型代码:主要用于封装纯js操作类型代码,会比较接近于mvc里m的概念。复用程度高。
* directive(指令)类型代码,通常封装操作dom的代码,譬如一个典型的标签页功能。复用程度高。
2. 尽量解耦js行为与css样式。 虽然已经存在众多的UI组件,但是其使用便捷性及移植性并不好。 譬如虽然jQuery提供了jQuery UI,但实际项目开发中,很少有人会直接使用jQuery UI的样式,很多时间精力花费在样式的修改上。考虑到这点,通过指令的形式(自定义html属性)提供基本的js行为,用户可以随意定义模板及样式;
doc
https://github.com/Julienedies/brick/wiki
example: ToDo 单独页面打开 all
htmljscss
// model
brick.services.reg('tasksModel', function () {
var recordManager = brick.services.get('recordManager')
var local = localStorage.getItem('tasksModel');
return new recordManager({
key: 'id',
eventPrefix: 'tasksModel',
broadcast: true
}).init(local && JSON.parse(local) || []);
});
//controller
brick.reg('tasksCtrl', function (scope) {
scope = this;
var tasksModel = brick.services.get('tasksModel')
var type = 0;
var render = function (e, msg) {
var model = type ? type === 1 ? tasksModel.get(false, 'complete') : tasksModel.get(true, 'complete') : tasksModel.get();
type === 0 && localStorage.setItem('tasksModel', JSON.stringify(model));
scope.render('task-list', {model:model});
};
scope.on('tasksModel.*', render);
scope.add = function (e) {
var val = this.value;
val && tasksModel.add({name: val, id: +new Date, complete: false});
this.value = '';
};
scope.edit = function (e) {
$(this).parent().find(':text').prop('disabled', false).focus();
};
scope.change = function (e) {
var parent = $(this).parent();
var id = parent.data('id');
var complete = parent.find(':checkbox').prop('checked');
var name = parent.find(':text').attr('disabled', true).val();
tasksModel.find(id).set({complete: !!complete, name: name});
};
scope.remove = function (e, id) {
tasksModel.find(id*1).remove();
};
scope.clear = function (e) {
tasksModel.find(true, 'complete').remove();
};
scope.$elm.find('[ic-tabs=b]').on('ic-tabs.change', function (e, msg) {
type = msg.activeTab.index() * 1;
render();
});
});
[ic-tabs=a] {
border-bottom: solid 1px #D6D6D6;
}
[ic-tabs=a] span {
display: inline-block;
padding: 0.5em 2em;
margin: 0 3px;
border-radius: 0.3em 0.3em 0 0;
border: solid 1px #D6D6D6;
margin-bottom: -1px;
}
[ic-tabs=a] span.active {
border-bottom: solid 1px #fff;
}
[ic-tabs=b] {
padding: 15px 0;
}
[ic-tabs=b] .active {
color: red;
}
.complete {
text-decoration: line-through;
}
[ic-ctrl=tasksCtrl] li {
position: relative;
list-style: none;;
border-bottom: 1px solid #ededed;
}
[ic-ctrl=tasksCtrl] [type=text] {
width: 76%;
padding: 0.5em 2%;
border: none;
background: transparent;
min-width: 20em;
padding: 0 0.5em;
border-radius: .2em;
height: 36px;
line-height: 36px;
border: solid 1px #ccd1d9;
}
[ic-ctrl=tasksCtrl] li [type=text] {
border: solid 1px transparent;
}
[ic-ctrl=tasksCtrl] li [type=text]:focus {
border: solid 1px #ccd1d9;
}
[ic-ctrl=tasksCtrl] button {
margin-left: 0.5em;
position: absolute;
top: 6px;
right: 0;
}