Beer -- Angular2 后台管理框架

来新公司这几个月在做车辆网的项目,我主要负责前台地图相关的开发,具体包括在地图上绘制车辆,绘制车辆轨迹,回放等。同时参与了其他几个系统管理模块的开发。前台,后台都接触过。 该项目用 SprintMVC + MyBatis + Redis 开发,在开发的过程中发现了几个问题:

  • 后台与前台开发界限不是很清晰,前台使用 .JSP 页面,数据绑定有时候用后台绑定,有时候又在前台发请求绑定。代码写着写着就疯了。

  • 前台页面的重复工作太多,比如系统管理中有司机管理,车辆管理,车组管理等,这个模块都有一个共同点:

  1. 相同的布局,页面分为上下两部分,上部分为查询区域,下部分为数据展示区域。所以每一个页面的网页代码基本一致。重复而枯燥。

  2. 相同的功能,每一个系统管理模块中的功能无非是增删改查,虽然项目中已经有一个公共 JS 模块方法来承担这个操作,但是在页面上,仍然需要写 onclick , onsubmit 这些事件。没有做到完全的封装。

  3. 每个页面布局一致,顶部菜单 + 左侧菜单 + 中心内容,问题是,现在切换每个页面都是整页刷新。而且现在的 JS,CSS 文件都没有做压缩合并,导致了每次切换页面都需要等 1,2 秒,作为一个前端工程师实在看去下去。这属于架构问题。说到这个问题,得从长计议。当时时间节点比较紧张,项目组采取人海战术,每个人负责几个页面,然后复制粘贴,就成现在这个样子了。(其实刚开始我是建议用 DIV + GET 的方法来模拟 iframe 的效果的。)

  4. 包括地图监控页面(我负责的页面),也是同样的问题,虽然地图打点等功能我已经封装了,在具体的页面直接调用方法就可以了,但是前台页面并没有完全的公用,要引用 baidu API 的脚本、要创建一个 DIV 标签,用来承载地图,还要初始化地图。。。 说到底,这些问题都可以归结为一个问题,没有做到模块化。

在之前发现这些问题的同时,我也考虑过使用组件化开发可能会解决。不过现成的框架并没有完全能够解决我的问题,要么就是有一些缺陷。因为我理想的框架是这样的:

  • 组件化开发,包括一些容器组件

  • 按需加载

  • 页面路由

  • 异步加载机制,很多框架不能同时做到异步加载和按需加载,除非做一些复杂的配置(类似 Vue.JS)

套用一句广告词,直到我发现了 Angular 2…更确切的说,直到 Angular 2 的正式版发布。

可以说,Angular 2 完全能够满足我的需求。 Angular 2 已经原生支持按需加载(依赖注入)和异步加载,组件化开发功能,当然,这套框架我不能直接拿到项目中使用,我需要在 Angular2 上面再做一层封装。目的是让业务开发人员尽可能的少写,少写,少写代码。

所以,我利用空闲时间写了一套后台管理框架,Beer。基于 Angular 2,最核心的几个组件如下:

Layout 用于页面的框架布局,也是容器组件,组装了三个子组件: Header , SideMenu, router-outlet(Content)

SideMenu 左侧菜单组件,是 Layout 的子组件,与 Content 组件互动,点击菜单,Content 显示相关的页面。

Header 顶部菜单。

router-outlet(Content) 页面展示区域。与 SideMenu 组件互动,点击菜单,SideMenu显示相关的页面。

Map 我最爱的组件,封装了地图显示,打点,轨迹回放等功能,想一想,只需要在页面中插入 <map></map> 标记,一个完完整整的地图就会出现,是多么神奇。

Manage 管理模块页面的容器组件,该组件高度封装了管理页面的公共部分和逻辑代码的公共部分。Manage 组件能让管理页面完全比用写不必要的代码,举个例子:比如司机管理的代码,这样写就可以了:

页面部分

1
<span class="hljs-tag"><<span class="hljs-name">div</span>></span> <span class="hljs-tag"><<span class="hljs-name">be-manage</span> [<span class="hljs-attr">canSearch</span>]=<span class="hljs-string">"true"</span> <span class="hljs-attr">manageName</span>=<span class="hljs-string">"driver"</span> [<span class="hljs-attr">searchModel</span>]=<span class="hljs-string">"searchModel"</span> [(<span class="hljs-attr">searchResult</span>)]=<span class="hljs-string">"drivers"</span>></span> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"search"</span>></span> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"ui-g"</span>></span> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"ui-g-4"</span>></span> 姓名 <span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">pInputText</span> /></span> <span class="hljs-tag"></<span class="hljs-name">div</span>></span> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"ui-g-4"</span>></span> 电话 <span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">pInputText</span> /></span> <span class="hljs-tag"></<span class="hljs-name">div</span>></span> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"ui-g-4"</span>></span> 驾驶证类型 <span class="hljs-tag"><<span class="hljs-name">p-dropdown</span> [<span class="hljs-attr">options</span>]=<span class="hljs-string">"carTypes"</span> [(<span class="hljs-attr">ngModel</span>)]=<span class="hljs-string">"searchModel.carType"</span>></span><span class="hljs-tag"></<span class="hljs-name">p-dropdown</span>></span> <span class="hljs-tag"></<span class="hljs-name">div</span>></span> <span class="hljs-tag"></<span class="hljs-name">div</span>></span> <span class="hljs-tag"></<span class="hljs-name">div</span>></span> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"list"</span>></span> <span class="hljs-tag"><<span class="hljs-name">p-dataTable</span> [<span class="hljs-attr">value</span>]=<span class="hljs-string">"drivers && drivers.rows"</span> <span class="hljs-attr">selectionMode</span>=<span class="hljs-string">"multiple"</span> [<span class="hljs-attr">rows</span>]=<span class="hljs-string">"5"</span> [<span class="hljs-attr">paginator</span>]=<span class="hljs-string">"true"</span> [<span class="hljs-attr">pageLinks</span>]=<span class="hljs-string">"3"</span>></span> <span class="hljs-tag"><<span class="hljs-name">p-column</span> [<span class="hljs-attr">style</span>]=<span class="hljs-string">"{'width':'38px'}"</span> <span class="hljs-attr">selectionMode</span>=<span class="hljs-string">"multiple"</span>></span><span class="hljs-tag"></<span class="hljs-name">p-column</span>></span> <span class="hljs-tag"><<span class="hljs-name">p-column</span> <span class="hljs-attr">field</span>=<span class="hljs-string">"eName"</span> <span class="hljs-attr">header</span>=<span class="hljs-string">"姓名"</span> [<span class="hljs-attr">sortable</span>]=<span class="hljs-string">"true"</span>></span><span class="hljs-tag"></<span class="hljs-name">p-column</span>></span> <span class="hljs-tag"><<span class="hljs-name">p-column</span> <span class="hljs-attr">field</span>=<span class="hljs-string">"address"</span> <span class="hljs-attr">header</span>=<span class="hljs-string">"地址"</span>></span><span class="hljs-tag"></<span class="hljs-name">p-column</span>></span> <span class="hljs-tag"></<span class="hljs-name">p-dataTable</span>></span> <span class="hljs-tag"></<span class="hljs-name">div</span>></span> <span class="hljs-tag"></<span class="hljs-name">be-manage</span>></span> <span class="hljs-tag"></<span class="hljs-name">div</span>></span>

` 脚本部分

1
2
3
4
5

@Component({
selector: <span class="hljs-string">'driver-editor'</span>,
templateUrl: <span class="hljs-string">'./app/system/driver/editor.component.html'</span>
})

最终效果

该框架现在刚刚起步开发,很多功能还需要完善和开发。目前做的这些功能是一个攻坚过程,攻坚的结果是,所有的技术点都已经解决,完完全全可以用 Beer 做一个车联网的后台项目。

但是人单力薄,想要完成一个健全的框架需要一些时间,我特别欢迎感兴趣的人参加到这个项目中来,该项目地址:
https://git.oschina.net/scaperow/Beer.git