您的位置:首页 > Web前端 > AngularJS

使用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

到目前为止他们仍在不断改进和提升。

如何获取代码

从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协议
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐