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; }