使用Angular2与WebApi开发SPA类型的企业应用 - Part 1- 概览
2016-12-23 22:18
453 查看
使用Angular2及RESTful WebApi开发SPA类型的企业应用 - Part 1 概览
作者:techcoaching,翻译:飘落寒冰
原文 有道
注:第一次翻译文章,有错译之处还请多多包涵,欢迎指出以便改进。
添加新角色
项目结构
多语言
依赖注入和控制反转-为什么和为什么不?
RESTful & WebApi
应用生命周期管理
应用构建与部署
注:代码所用的Angular2 为RC版
当今,随着Web开发的日益增加,越来越多的桌面应用(例如HRM,CRM,工资系统…)已经迁移成为Web应用。
Web应用可以使用Web环境的诸多好处。我们很容易就可以检索到大量Web应用与桌面应用之间的利弊分析,在此我们不做讨论。
本系列的文章主要是为了帮助你组织管理你的下列类型的项目
目前一些非常流行的技术:
Angular2 (typescript)
WebApi (RESTful)
Entity Framework
Bootstrap
IoC
Multi-Layer architecture
Modular your Application
Multi Languages
Design Pattern (Unit Of Work, Repository, …)
SOLID principle
Gulp
NodeJs
到目前为止他们仍在不断改进和提升。
- Client: 客户端代码,typescript写成,使用angular2框架。
- Api: 服务器段代码,用来处理客户端的请求
Nodejs: https://nodejs.org/en/
Visual Code: https://code.visualstudio.com
运行app
打开命令行并跳转到客户端的根目录
键入“npm install”,安装确实的NodeJS包
使用“npm start”,运行app
控制台输出
浏览器输出
到这一步,客户端运行成功
在VS2015中打开 Api 项目
按F5 使用IIS Express运行程序,我们将在浏览器中看到以下输出:
如果配置过默认路由,将不会看到这个错误页面
使用tu.tran@yahoo.com/123456登录,我们将看到下面的默认页面(可以在应用配置中变更):
- 列出完成该页面的所有需要实现的步骤。
- 找出缺少的信息,然后立即寻求帮助
- 思考从客户端到服务器端的逻辑流程,从UI到数据访问,这有助于我们更好的编码。我的很多同事习惯先写代码,然后Debug。当有错误发生时,它令你不得不修改代码去维持系统运转,这样做很可能打破系统的逻辑流程,而且修改的代码往往不太符合该程序开发的结构与规范。这些将来可能会引发新的潜在的问题并且代码难以维护。
分析完页面之后,我们找出了以下需要完成的事情:
客户端
创建新的模块(命名为security),我将谈论到一些模块化应用程序的优缺点。
为角色组件(Angular里称page为组件)注册路由,并为其分配菜单信息(左侧面板的子菜单)
将该组件的配置项导入并注册到应用配置中。
创建组件文件(UI的html文件,逻辑处理的ts文件,组件视图模型的ts文件)
实现角色管理组件的UI
实现角色管理的逻辑(包含请求服务器及获取数据)
实现页面的请求(请求通过调用REST api来获取授权列表)
服务器API
增加名为RolesController的Controller来处理角色的相关请求
增加RoleService和RoleRepository来获取角色列表(本文采用多层架构)
在DbContext中增加实体类
接来下我们一步一步来讲
1. 创建一个新的模块(命名为security)。按照惯例,我们在”/app/modules/secutiry/_share/config”创建一个新的module.ts文件,如下:
创建route.ts文件
在此文件,我们将为security模块提供一个配置信息,例如:子菜单列表,模块路由
2. 为Roles组件注册路由和子菜单信息,将该行内容加入到上一步创建的module.ts文件中。
3. 将该模块的配置导入和注册到应用配置中。下面的代码把security模块注册到应用中,该模块和它的子菜
d0a0
单将在左侧列表中显示。
系统会自动为security模块注册路由。
4. 创建组件文件(UI的html文件,逻辑处理的ts文件,组件视图模型的ts文件)
5. 实现角色组件的UI。这里有一些本文会用到的指令已经创建出来,我将在其他的文件里介绍这些指令的细节。
在此Html中,我们用了:
- “grid”指令,显示角色列表。包含了若干我们可以处理的事件和在mode.options属性中定义的列
- “page-action”指令,在角色列表之上显示“添加角色”,如图
- page, page-header, page-content指令,这些是我的框架体系中页面结构指令
6. 实现角色组件的逻辑(包含请求服务器及获取数据)
为定义新的组件我们需要:
- 为组件指定模板文件(9行)
- 声明在组件中用到的指令(11行),如果指令没有被声明,在组件文件中他将不会被渲染,angular会将其标签(page-action/>, )解释成html标签
- 为BasePage声明新的角色类
- 为组件声明视图模型。每个组件必须包含自己的视图模型。这将帮助我们降低role.ts文件的复杂性
- 通过请求Api,调用roleService的相关方法,获取数据。我们将这些工作挪到service中可以使role.
注:我们在RolesModel的构造器中使用了i18nHelper,他将帮助我们解决表格列标题正确显示当前语言(多语言支持)
7. 实现页面的请求(请求通过调用REST api来获取授权列表)
这是一个通过请求REST api来获取角色列表的简单例子,更多IConnection的信息可以参考/app/common/connectors/RESTConnector.ts
1. Api 项目结构
- App.Common: 该目录包含了app各部门用到的基础代码。
- App.Api: 客户端可以调用对外公开的REST Api。
- App.Service: 包含所有的service接口及相应的数据传输对象。
- App.Service.Impl: 只包含对应的service接口的实现。
- App.Repository: 包含所有的数据访问接口。每个数据仓库只操作数据库中的一个实体模型。
- App.Repository.Impl: 只包含对应的数据访问接口的实现。
- App.Entity: 包含App中所有的实体模型。
- App.Context: 在本示例中,它包含我们在使用EF framework时所有的DbContext。我计划在将来将他和App.Entity合并。
注:我们只用接口在各层之间的进行通信(例如: App.Api -> App.Service => App.Repository)。
2. 增加名为RolesController的Controller来处理角色的相关请求。
按照本app的约定,我们在”App.Api/Features/Security”创建了RolesController。
我觉得这部分代码很简单。在controller中我们通过调用对应的service中的“GetRoles”,来获取角色列表(DTO)。
IoC将返回service中接口的实例
在 App.Service.Impl中,我们使用了boostrap.cs文件,我们在此注册了接口与其对应实现的实例。
增加RoleService和RoleService来获取角色列表(本文采用多层架构)
注:
- 我们需要为每个action定义对应的DTO,大部分情况我们只需要实体模型的部分属性,这样有助于简化代码,并且在将来容易维护。
- RoleService 类并定义成internal,而不是public,所以外部无法创建该类的实例
4. 增加IRoleRepository和RoleRepository for getting the list of Roles
注:同RoleService一样, RoleRepository也被定义为internal.只有接口能被Project以外调用。
5. 在DbContext中增加实体类
在下一片中,我将讲如何创建和更新角色,并将介绍该架构的更多细节(例如:项目结构,指令…)
作者:techcoaching,翻译:飘落寒冰
原文 有道
注:第一次翻译文章,有错译之处还请多多包涵,欢迎指出以便改进。
该系列的全部文章
概览添加新角色
项目结构
多语言
依赖注入和控制反转-为什么和为什么不?
RESTful & WebApi
应用生命周期管理
应用构建与部署
简介
首先我跟大家分享的是“我们不是在学习技术,而是在学习怎样使用技术为我们的商业服务”。注:代码所用的Angular2 为RC版
当今,随着Web开发的日益增加,越来越多的桌面应用(例如HRM,CRM,工资系统…)已经迁移成为Web应用。
Web应用可以使用Web环境的诸多好处。我们很容易就可以检索到大量Web应用与桌面应用之间的利弊分析,在此我们不做讨论。
本系列的文章主要是为了帮助你组织管理你的下列类型的项目
目前一些非常流行的技术:
Angular2 (typescript)
WebApi (RESTful)
Entity Framework
Bootstrap
IoC
Multi-Layer architecture
Modular your Application
Multi Languages
Design Pattern (Unit Of Work, Repository, …)
SOLID principle
Gulp
NodeJs
到目前为止他们仍在不断改进和提升。
如何获取代码
从Github上下载源码https://github.com/techcoaching/TinyERP.git如何运行代码
代码分配在2个目录- Client: 客户端代码,typescript写成,使用angular2框架。
- Api: 服务器段代码,用来处理客户端的请求
运行客户端:
运行客户端代码,首先需要安装:Nodejs: https://nodejs.org/en/
Visual Code: https://code.visualstudio.com
运行app
打开命令行并跳转到客户端的根目录
键入“npm install”,安装确实的NodeJS包
使用“npm start”,运行app
控制台输出
浏览器输出
到这一步,客户端运行成功
运行API
第一次运行,我们需要更新app.common\configurations\configuration.(debug|release).config文件中的connectionstring在VS2015中打开 Api 项目
按F5 使用IIS Express运行程序,我们将在浏览器中看到以下输出:
如果配置过默认路由,将不会看到这个错误页面
应用初探
首先我们需要登录使用tu.tran@yahoo.com/123456登录,我们将看到下面的默认页面(可以在应用配置中变更):
角色列表页面
在这一部分,我们将展示如何实现一个新页面分析
我习惯在实现页面之前先做分析,能帮我们发现:- 列出完成该页面的所有需要实现的步骤。
- 找出缺少的信息,然后立即寻求帮助
- 思考从客户端到服务器端的逻辑流程,从UI到数据访问,这有助于我们更好的编码。我的很多同事习惯先写代码,然后Debug。当有错误发生时,它令你不得不修改代码去维持系统运转,这样做很可能打破系统的逻辑流程,而且修改的代码往往不太符合该程序开发的结构与规范。这些将来可能会引发新的潜在的问题并且代码难以维护。
分析完页面之后,我们找出了以下需要完成的事情:
客户端
创建新的模块(命名为security),我将谈论到一些模块化应用程序的优缺点。
为角色组件(Angular里称page为组件)注册路由,并为其分配菜单信息(左侧面板的子菜单)
将该组件的配置项导入并注册到应用配置中。
创建组件文件(UI的html文件,逻辑处理的ts文件,组件视图模型的ts文件)
实现角色管理组件的UI
实现角色管理的逻辑(包含请求服务器及获取数据)
实现页面的请求(请求通过调用REST api来获取授权列表)
服务器API
增加名为RolesController的Controller来处理角色的相关请求
增加RoleService和RoleRepository来获取角色列表(本文采用多层架构)
在DbContext中增加实体类
接来下我们一步一步来讲
实现客户端
在本节,目录为客户端所在目录1. 创建一个新的模块(命名为security)。按照惯例,我们在”/app/modules/secutiry/_share/config”创建一个新的module.ts文件,如下:
创建route.ts文件
在此文件,我们将为security模块提供一个配置信息,例如:子菜单列表,模块路由
2. 为Roles组件注册路由和子菜单信息,将该行内容加入到上一步创建的module.ts文件中。
3. 将该模块的配置导入和注册到应用配置中。下面的代码把security模块注册到应用中,该模块和它的子菜
d0a0
单将在左侧列表中显示。
系统会自动为security模块注册路由。
4. 创建组件文件(UI的html文件,逻辑处理的ts文件,组件视图模型的ts文件)
5. 实现角色组件的UI。这里有一些本文会用到的指令已经创建出来,我将在其他的文件里介绍这些指令的细节。
在此Html中,我们用了:
- “grid”指令,显示角色列表。包含了若干我们可以处理的事件和在mode.options属性中定义的列
- “page-action”指令,在角色列表之上显示“添加角色”,如图
- page, page-header, page-content指令,这些是我的框架体系中页面结构指令
6. 实现角色组件的逻辑(包含请求服务器及获取数据)
为定义新的组件我们需要:
- 为组件指定模板文件(9行)
- 声明在组件中用到的指令(11行),如果指令没有被声明,在组件文件中他将不会被渲染,angular会将其标签(page-action/>, )解释成html标签
- 为BasePage声明新的角色类
- 为组件声明视图模型。每个组件必须包含自己的视图模型。这将帮助我们降低role.ts文件的复杂性
- 通过请求Api,调用roleService的相关方法,获取数据。我们将这些工作挪到service中可以使role.
注:我们在RolesModel的构造器中使用了i18nHelper,他将帮助我们解决表格列标题正确显示当前语言(多语言支持)
7. 实现页面的请求(请求通过调用REST api来获取授权列表)
这是一个通过请求REST api来获取角色列表的简单例子,更多IConnection的信息可以参考/app/common/connectors/RESTConnector.ts
实现API
在此节,目录为api代码所在目录.1. Api 项目结构
- App.Common: 该目录包含了app各部门用到的基础代码。
- App.Api: 客户端可以调用对外公开的REST Api。
- App.Service: 包含所有的service接口及相应的数据传输对象。
- App.Service.Impl: 只包含对应的service接口的实现。
- App.Repository: 包含所有的数据访问接口。每个数据仓库只操作数据库中的一个实体模型。
- App.Repository.Impl: 只包含对应的数据访问接口的实现。
- App.Entity: 包含App中所有的实体模型。
- App.Context: 在本示例中,它包含我们在使用EF framework时所有的DbContext。我计划在将来将他和App.Entity合并。
注:我们只用接口在各层之间的进行通信(例如: App.Api -> App.Service => App.Repository)。
2. 增加名为RolesController的Controller来处理角色的相关请求。
按照本app的约定,我们在”App.Api/Features/Security”创建了RolesController。
namespace App.Api.Features.Security { [RoutePrefix("api/roles")] public class RolesController : ApiController { [HttpGet] [Route("")] public IResponseData<IList<RoleListItemSummary>> GetRoles() { IResponseData<IList<RoleListItemSummary>> response = new ResponseData<IList<RoleListItemSummary>>(); try { IRoleService roleService = IoC.Container.Resolve<IRoleService>(); IList<RoleListItemSummary> roles=roleService.GetRoles(); response.SetData(roles); } catch (ValidationException ex) { response.SetErrors(ex.Errors); response.SetStatus(System.Net.HttpStatusCode.PreconditionFailed); } return response; } } }
我觉得这部分代码很简单。在controller中我们通过调用对应的service中的“GetRoles”,来获取角色列表(DTO)。
IoC将返回service中接口的实例
在 App.Service.Impl中,我们使用了boostrap.cs文件,我们在此注册了接口与其对应实现的实例。
namespace App.Service.Impl { public class Bootstrap : App.Common.Tasks.BaseTask<IBaseContainer>, IBootstrapper { public Bootstrap():base(App.Common.ApplicationType.All) { } public void Execute(IBaseContainer context) { context.RegisterSingleton<App.Service.Security.IRoleService, App.Service.Impl.Security.RoleService>(); } } }
增加RoleService和RoleService来获取角色列表(本文采用多层架构)
namespace App.Service.Security { public interface IRoleService { System.Collections.Generic.IList<RoleListItemSummary> GetRoles(); } } namespace App.Service.Impl.Security { internal class RoleService : IRoleService { public IList<RoleListItemSummary> GetRoles() { IRoleRepository repository = IoC.Container.Resolve<IRoleRepository>(); return repository.GetItems<RoleListItemSummary>(); } } }
注:
- 我们需要为每个action定义对应的DTO,大部分情况我们只需要实体模型的部分属性,这样有助于简化代码,并且在将来容易维护。
- RoleService 类并定义成internal,而不是public,所以外部无法创建该类的实例
4. 增加IRoleRepository和RoleRepository for getting the list of Roles
namespace App.Repository.Secutiry { public interface IRoleRepository: App.Common.Data.IBaseContentRepository<Role> { } } namespace App.Repository.Impl.Security { internal class RoleRepository: BaseContentRepository<Role>, IRoleRepository { public RoleRepository() : base(new App.Context.AppDbContext(App.Common.IOMode.Read)) { } public RoleRepository(IUnitOfWork uow) : base(uow.Context as IMSSQLDbContext) { } } }
注:同RoleService一样, RoleRepository也被定义为internal.只有接口能被Project以外调用。
5. 在DbContext中增加实体类
namespace App.Entity.Security { public class Role:BaseContent { public IList<Permission> Permissions { get; set; } public Role():base() { this.Permissions = new List<Permission>(); } public Role(string name, string desc, IList<Permission> permissions): this() { this.Name = name; this.Key = App.Common.Helpers.UtilHelper.ToKey(name); this.Description = desc; if (permissions == null) { return; } this.Permissions = permissions; } } } namespace App.Context { public class AppDbContext : App.Common.Data.MSSQL.MSSQLDbContext { public AppDbContext(IOMode mode = IOMode.Read) : base(new App.Common.Data.MSSQL.MSSQLConnectionString(), mode) { } public System.Data.Entity.DbSet<Role> Roles { get; set; } } }
总结
在本文中,我概述了SPA项目,在UI里如何获取和显示角色列表。在下一片中,我将讲如何创建和更新角色,并将介绍该架构的更多细节(例如:项目结构,指令…)
授权
本文,以及所包含的源码,文件遵循CPOL协议相关文章推荐
- 使用Angular2及WebApi开发SPA类型的企业应用 - Part 6- RESTful 和 WebApi
- 使用Angular2及WebApi开发SPA类型的企业应用 - Part 3 项目结构
- 使用Angular2及WebApi开发SPA类型的企业应用 - Part 2- 添加新角色
- 使用Angular2及WebApi开发SPA类型的企业应用 - Part 7- 应用运行周期管理
- 使用jBPM开发企业流程应用之在Tomcat上部署流程引擎及控制台
- Flex企业应用开发实践学习笔记(六)——使用ActionScript创建自定义组件
- OSGI企业应用开发(四)使用Blueprint整合Spring框架(一)
- OSGI企业应用开发(五)使用Blueprint整合Spring框架(二)
- 使用Oracle Virtual Assembly Builder开发虚拟化企业应用
- 【读书笔记】WebApi 和 SPA(单页应用)--knockout的使用
- OSGI企业应用开发(四)使用Blueprint整合Spring框架(一)
- Android应用开发之使用SharedPreferences存储复杂类型的数据
- SAP企业移动平台开发探索系列6 – 使用SUP开发Android离线应用
- [置顶] OSGI企业应用开发(四)使用Blueprint整合Spring框架(一)
- 使用jBPM开发企业流程应用之安装流程设计器
- SAP企业移动平台开发探索系列9 – 使用SenchaTouch第三方UI开发HWC应用
- Swift - 判断设备类型开发兼容的iOS应用(iPad使用分隔视图控制器)
- 使用EasyWechat开发java微信公众平台应用(三)——接受不同类型的消息
- [置顶] OSGI企业应用开发(五)使用Blueprint整合Spring框架(二)
- OSGI企业应用开发(五)使用Blueprint整合Spring框架(二)