首页 >

如何使用AngularJs打造权限管理系统【简易型】_AngularJS

web前端|js教程如何使用AngularJs打造权限管理系统【简易型】_AngularJS
angularjs管理系统,angularjs权限管理系统
web前端-js教程
A、引言
投融资信息平台 源码,vscode gdb调试,ubuntu coda,tomcat 报错500,sqlite3建索引,wordpress 游戏插件,如何开发一个前端框架,python爬虫可视化原理,php 数据同步,周村seo优化,php网站模板免费下载,网页右侧返回首页,系统底层模板lzw
  本文将介绍如何把AngularJs应用到实际项目中。本篇文章将使用AngularJS来打造一个简易的权限管理系统。下面不多说,直接进入主题。
淘简单程序源码,vscode提示中文,玩客云免串口刷入ubuntu,tomcat主程序,sqlite怎么导入表,jquery图像插件,市场三大主流前端框架,有意义的爬虫,php 扩展mysqli,谷歌seo未来,如何偷别人dedecms网站的模板,c 写网页源码,个人相册网站模板中文lzw
B、整体架构设计介绍
企业网站源码带商城,ubuntu扩展磁盘大小,设置tomcat6的内存,C语言爬虫程序,html怎么传输数据给php,seo童装软文lzw
  首先看下整个项目的架构设计图:

从上图可以看出整个项目的一个整体结构,接下来,我来详细介绍了项目的整体架构:

采用Asp.net Web API来实现REST 服务。这样的实现方式,已达到后端服务的公用、分别部署和更好地扩展。Web层依赖应用服务接口,并且使用Castle Windsor实现依赖注入。

显示层(用户UI)

显示层采用了AngularJS来实现的SPA页面。所有的页面数据都是异步加载和局部刷新,这样的实现将会有更好的用户体验。

应用层(Application Service)

AngularJS通过Http服务去请求Web API来获得数据,而Web API的实现则是调用应用层来请求数据。

基础架构层

基础架构层包括仓储的实现和一些公用方法的实现。

仓储层的实现采用EF Code First的方式来实现的,并使用EF Migration的方式来创建数据库和更新数据库。

LH.Common层实现了一些公用的方法,如日志帮助类、表达式树扩展等类的实现。

领域层

领域层主要实现了该项目的所有领域模型,其中包括领域模型的实现和仓储接口的定义。

介绍完整体结构外,接下来将分别介绍该项目的后端服务实现和Web前端的实现。

C、后端服务实现

后端服务主要采用Asp.net Web API来实现后端服务,并且采用Castle Windsor来完成依赖注入。

这里拿权限管理中的用户管理来介绍Rest Web API服务的实现。

提供用户数据的REST服务的实现:

public class UserController : ApiController {  private readonly IUserService _userService;  public UserController(IUserService userService)  {   _userService = userService;  }  [HttpGet]  [Route("api/user/GetUsers")]  public OutputBase GetUsers([FromUri]PageInput input)  {   return _userService.GetUsers(input);  }  [HttpGet]  [Route("api/user/UserInfo")]  public OutputBase GetUserInfo(int id)  {   return _userService.GetUser(id);  }  [HttpPost]  [Route("api/user/AddUser")]  public OutputBase CreateUser([FromBody] UserDto userDto)  {   return _userService.AddUser(userDto);  }  [HttpPost]  [Route("api/user/UpdateUser")]  public OutputBase UpdateUser([FromBody] UserDto userDto)  {   return _userService.UpdateUser(userDto);  }  [HttpPost]  [Route("api/user/UpdateRoles")]  public OutputBase UpdateRoles([FromBody] UserDto userDto)  {   return _userService.UpdateRoles(userDto);  }  [HttpPost]  [Route("api/user/DeleteUser/{id}")]  public OutputBase DeleteUser(int id)  {   return _userService.DeleteUser(id);  }  [HttpPost]  [Route("api/user/DeleteRole/{id}/{roleId}")]  public OutputBase DeleteRole(int id, int roleId)  {   return _userService.DeleteRole(id, roleId);  } }
  从上面代码实现可以看出,User REST 服务依赖与IUserService接口,并且也没有像传统的方式将所有的业务逻辑放在Web API实现中,而是将具体的一些业务实现封装到对应的应用层中,Rest API只负责调用对应的应用层中的服务。这样设计好处有:

REST 服务部依赖与应用层接口,使得职责分离,将应用层服务的实例化交给单独的依赖注入容器去完成,而REST服务只负责调用对应应用服务的方法来获取数据。采用依赖接口而不依赖与具体类的实现,使得类与类之间低耦合。REST服务内不包括具体的业务逻辑实现。这样的设计可以使得服务更好地分离,如果你后期想用WCF来实现REST服务的,这样就不需要重复在WCF的REST服务类中重复写一篇Web API中的逻辑了,这时候完全可以调用应用服务的接口方法来实现WCF REST服务。所以将业务逻辑实现抽到应用服务层去实现,这样的设计将使得REST 服务职责更加单一,REST服务实现更容易扩展。

用户应用服务的实现:

public class UserService : BaseService, IUserService {  private readonly IUserRepository _userRepository;  private readonly IUserRoleRepository _userRoleRepository;  public UserService(IUserRepository userRepository, IUserRoleRepository userRoleRepository)  {   _userRepository = userRepository;   _userRoleRepository = userRoleRepository;  }  public GetResults GetUsers(PageInput input)  {   var result = GetDefault<GetResults>();   var filterExp = BuildExpression(input);   var query = _userRepository.Find(filterExp, user => user.Id, SortOrder.Descending, input.Current, input.Size);   result.Total = _userRepository.Find(filterExp).Count();   result.Data = query.Select(user => new UserDto()   {    Id = user.Id,    CreateTime = user.CreationTime,    Email = user.Email,    State = user.State,    Name = user.Name,    RealName = user.RealName,    Password = "*******",    Roles = user.UserRoles.Take(4).Select(z => new BaseEntityDto()    {     Id = z.Role.Id,     Name = z.Role.RoleName    }).ToList(),    TotalRole = user.UserRoles.Count()   }).ToList();   return result;  }  public UpdateResult UpdateUser(UserDto user)  {   var result = GetDefault();   var existUser = _userRepository.FindSingle(u => u.Id == user.Id);   if (existUser == null)   {    result.Message = "USER_NOT_EXIST";    result.StateCode = 0x00303;    return result;   }   if (IsHasSameName(existUser.Name, existUser.Id))   {    result.Message = "USER_NAME_HAS_EXIST";    result.StateCode = 0x00302;    return result;   }   existUser.RealName = user.RealName;   existUser.Name = user.Name;   existUser.State = user.State;   existUser.Email = user.Email;   _userRepository.Update(existUser);   _userRepository.Commit();   result.IsSaved = true;   return result;  }  public CreateResult AddUser(UserDto userDto)  {   var result = GetDefault<CreateResult>();   if (IsHasSameName(userDto.Name, userDto.Id))   {    result.Message = "USER_NAME_HAS_EXIST";    result.StateCode = 0x00302;    return result;   }   var user = new User()   {    CreationTime = DateTime.Now,    Password = "",    Email = userDto.Email,    State = userDto.State,    RealName = userDto.RealName,    Name = userDto.Name   };   _userRepository.Add(user);   _userRepository.Commit();   result.Id = user.Id;   result.IsCreated = true;   return result;  }  public DeleteResult DeleteUser(int userId)  {   var result = GetDefault();   var user = _userRepository.FindSingle(x => x.Id == userId);   if (user != null)   {    _userRepository.Delete(user);    _userRepository.Commit();   }   result.IsDeleted = true;   return result;  }  public UpdateResult UpdatePwd(UserDto user)  {   var result = GetDefault();   var userEntity =_userRepository.FindSingle(x => x.Id == user.Id);   if (userEntity == null)   {    result.Message = string.Format("当前编辑的用户“{0}”已经不存在", user.Name);    return result;   }   userEntity.Password = user.Password;   _userRepository.Commit();   result.IsSaved = true;   return result;  }  public GetResult GetUser(int userId)  {   var result = GetDefault<GetResult>();   var model = _userRepository.FindSingle(x => x.Id == userId);   if (model == null)   {    result.Message = "USE_NOT_EXIST";    result.StateCode = 0x00402;    return result;   }   result.Data = new UserDto()   {    CreateTime = model.CreationTime,    Email = model.Email,    Id = model.Id,    RealName = model.RealName,    State = model.State,    Name = model.Name,    Password = "*******"   };   return result;  }  public UpdateResult UpdateRoles(UserDto user)  {   var result = GetDefault();   var model = _userRepository.FindSingle(x => x.Id == user.Id);   if (model == null)   {    result.Message = "USE_NOT_EXIST";    result.StateCode = 0x00402;    return result;   }   var list = model.UserRoles.ToList();   if (user.Roles != null)   {    foreach (var item in user.Roles)    {     if (!list.Exists(x => x.Role.Id == item.Id))     {      _userRoleRepository.Add(new UserRole { RoleId = item.Id, UserId = model.Id });     }    }    foreach (var item in list)    {     if (!user.Roles.Exists(x => x.Id == item.Id))     {      _userRoleRepository.Delete(item);     }    }    _userRoleRepository.Commit();    _userRepository.Commit();   }   result.IsSaved = true;   return result;  }  public DeleteResult DeleteRole(int userId, int roleId)  {   var result = GetDefault();   var model = _userRoleRepository.FindSingle(x => x.UserId == userId && x.RoleId == roleId);   if (model != null)   {    _userRoleRepository.Delete(model);    _userRoleRepository.Commit();   }   result.IsDeleted = true;   return result;  }  public bool Exist(string username, string password)  {   return _userRepository.FindSingle(u => u.Name == username && u.Password == password) != null;  }  private bool IsHasSameName(string name, int userId)  {   return !string.IsNullOrWhiteSpace(name) && _userRepository.Find(u=>u.Name ==name && u.Id != userId).Any();  }  private Expression<Func> BuildExpression(PageInput pageInput)  {   Expression<Func> filterExp = user => true;   if (string.IsNullOrWhiteSpace(pageInput.Name))    return filterExp;   switch (pageInput.Type)   {    case 0:     filterExp = user => user.Name.Contains(pageInput.Name) || user.Email.Contains(pageInput.Name);     break;    case 1:     filterExp = user => user.Name.Contains(pageInput.Name);     break;    case 2:     filterExp = user => user.Email.Contains(pageInput.Name);     break;   }   return filterExp;  } }
  这里应用服务层其实还可以进一步的优化,实现代码层级的读写分离,定义IReadOnlyService接口和IWriteServie接口,并且把写操作可以采用泛型方法的方式抽象到BaseService中去实现。这样一些增删改操作实现公用,之所以可以将这里操作实现公用,是因为这些操作都是非常类似的,无非是操作的实体不一样罢了。其实这样的实现在我另一个开源项目中已经用到:OnlineStore.大家可以参考这个自行去实现。

仓储层的实现:

用户应用服务也没有直接依赖与具体的仓储类,同样也是依赖其接口。对应的用户仓储类的实现如下:

public class BaseRepository : IRepository  where TEntity :class , IEntity {  private readonly ThreadLocal _localCtx = new ThreadLocal(() => new UserManagerDBContext());  public UserManagerDBContext DbContext { get { return _localCtx.Value; } }  public TEntity FindSingle(Expression<Func> exp = null)  {   return DbContext.Set().AsNoTracking().FirstOrDefault(exp);  }  public IQueryable Find(Expression<Func> exp = null)  {   return Filter(exp);  }  public IQueryable Find(Expression<Func> expression, Expression<Func> sortPredicate, SortOrder sortOrder, int pageNumber, int pageSize)  {   if (pageNumber <= 0)    throw new ArgumentOutOfRangeException("pageNumber", pageNumber, "pageNumber must great than or equal to 1.");   if (pageSize <= 0)    throw new ArgumentOutOfRangeException("pageSize", pageSize, "pageSize must great than or equal to 1.");   var query = DbContext.Set().Where(expression);   var skip = (pageNumber - 1) * pageSize;   var take = pageSize;   if (sortPredicate == null)    throw new InvalidOperationException("Based on the paging query must specify sorting fields and sort order.");   switch (sortOrder)   {    case SortOrder.Ascending:     var pagedAscending = query.SortBy(sortPredicate).Skip(skip).Take(take);     return pagedAscending;    case SortOrder.Descending:     var pagedDescending = query.SortByDescending(sortPredicate).Skip(skip).Take(take);     return pagedDescending;   }   throw new InvalidOperationException("Based on the paging query must specify sorting fields and sort order.");  }  public int GetCount(Expression<Func> exp = null)  {   return Filter(exp).Count();  }  public void Add(TEntity entity)  {   DbContext.Set().Add(entity);  }  public void Update(TEntity entity)  {   DbContext.Entry(entity).State = EntityState.Modified;  }  public void Delete(TEntity entity)  {   DbContext.Entry(entity).State = EntityState.Deleted;   DbContext.Set().Remove(entity);  }  public void Delete(ICollection entityCollection)  {   if(entityCollection.Count ==0)    return;   DbContext.Set().Attach(entityCollection.First());   DbContext.Set().RemoveRange(entityCollection);  }  private IQueryable Filter(Expression<Func> exp)  {   var dbSet = DbContext.Set().AsQueryable();   if (exp != null)    dbSet = dbSet.Where(exp);   return dbSet;  }  public void Commit()  {   DbContext.SaveChanges();  } }public class UserRepository :BaseRepository, IUserRepository { }
D、AngularJS前端实现

Web前端的实现就是采用AngularJS来实现,并且采用模块化开发模式。具体Web前端的代码结构下图例:

App/images // 存放Web前端使用的图片资源App/Styles // 存放样式文件App/scripts // 整个Web前端用到的脚本文件    / Controllers // angularJS控制器模块存放目录    / directives // angularJs指令模块存放目录    / filters // 过滤器模块存放目录    / services // 服务模块存放目录   / app.js // Web前端程序配置模块(路由配置)App/Modules // 项目依赖库,angular、Bootstrap、Jquery库App/Views // AngularJs视图模板存放目录
  使用AngularJS开发的Web应用程序的代码之间的调用层次和后端基本一致,也是视图页面——》控制器模块——》服务模块——》Web API服务。

并且Web前端CSS和JS资源的加载采用了Bundle的方式来减少请求资源的次数,从而加快页面加载时间。具体Bundle类的配置:

public class BundleConfig {  // For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862  public static void RegisterBundles(BundleCollection bundles)  {   //类库依赖文件   bundles.Add(new ScriptBundle("~/js/base/lib").Include(     "~/app/modules/jquery-1.11.2.min.js",     "~/app/modules/angular/angular.min.js",     "~/app/modules/angular/angular-route.min.js",     "~/app/modules/bootstrap/js/ui-bootstrap-tpls-0.13.0.min.js",     "~/app/modules/bootstrap-notify/bootstrap-notify.min.js"     ));   //angularjs 项目文件   bundles.Add(new ScriptBundle("~/js/angularjs/app").Include(     "~/app/scripts/services/*.js",     "~/app/scripts/controllers/*.js",     "~/app/scripts/directives/*.js",     "~/app/scripts/filters/*.js",     "~/app/scripts/app.js"));   //样式   bundles.Add(new StyleBundle("~/js/base/style").Include(     "~/app/modules/bootstrap/css/bootstrap.min.css",     "~/app/styles/dashboard.css",     "~/app/styles/console.css"     ));  } }
  首页 Index.cshtml

  简易权限管理系统Demo @Styles.Render("~/js/base/style") @Scripts.Render("~/js/base/lib")  
@Scripts.Render("~/js/angularjs/app")
E、运行效果

介绍完前后端的实现之后,接下来让我们看下整个项目的运行效果:

F、总结

到此,本文的所有内容都介绍完了,尽管本文的AngularJS的应用项目还有很多完善的地方,例如没有缓冲的支持、没有实现读写分离,没有对一些API进行压力测试等。但AngularJS在实际项目中的应用基本是这样的,大家如果在项目中有需要用到AngularJS,正好你们公司的后台又是.NET的话,相信本文的分享可以是一个很好的参考。另外,关于架构的设计也可以参考我的另一个开源项目:OnlineStore和FastWorks。

以上所述是小编给大家介绍的使用AngularJs打造权限管理系统的方法,希望对大家有所帮助!


  • 暂无相关文章