欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

AngularJs篇:使用AngularJs打造一個簡易權限系統(tǒng)的實現(xiàn)代碼

 更新時間:2016年12月26日 10:08:14   作者:Learning hard  
本篇文章主要介紹了AngularJs篇:使用AngularJs打造一個簡易權限系統(tǒng)的實現(xiàn)代碼,具有一定的參考價值,有興趣的可以了解一下。

一、引言

上一篇博文已經(jīng)向大家介紹了AngularJS核心的一些知識點,在這篇博文將介紹如何把AngularJs應用到實際項目中。本篇博文將使用AngularJS來打造一個簡易的權限管理系統(tǒng)。下面不多說,直接進入主題。

二、整體架構設計介紹

首先看下整個項目的架構設計圖:

從上圖可以看出整個項目的一個整體結構,接下來,我來詳細介紹了項目的整體架構:

采用Asp.net Web API來實現(xiàn)REST 服務。這樣的實現(xiàn)方式,已達到后端服務的公用、分別部署和更好地擴展。Web層依賴應用服務接口,并且使用Castle Windsor實現(xiàn)依賴注入。

1、顯示層(用戶UI)

顯示層采用了AngularJS來實現(xiàn)的SPA頁面。所有的頁面數(shù)據(jù)都是異步加載和局部刷新,這樣的實現(xiàn)將會有更好的用戶體驗。

2、應用層(Application Service)

AngularJS通過Http服務去請求Web API來獲得數(shù)據(jù),而Web API的實現(xiàn)則是調(diào)用應用層來請求數(shù)據(jù)。

3、基礎架構層

基礎架構層包括倉儲的實現(xiàn)和一些公用方法的實現(xiàn)。

倉儲層的實現(xiàn)采用EF Code First的方式來實現(xiàn)的,并使用EF Migration的方式來創(chuàng)建數(shù)據(jù)庫和更新數(shù)據(jù)庫。

LH.Common層實現(xiàn)了一些公用的方法,如日志幫助類、表達式樹擴展等類的實現(xiàn)。

4、領域層

領域層主要實現(xiàn)了該項目的所有領域模型,其中包括領域模型的實現(xiàn)和倉儲接口的定義。

介紹完整體結構外,接下來將分別介紹該項目的后端服務實現(xiàn)和Web前端的實現(xiàn)。

三、后端服務實現(xiàn)

后端服務主要采用Asp.net Web API來實現(xiàn)后端服務,并且采用Castle Windsor來完成依賴注入。

這里拿權限管理中的用戶管理來介紹Rest Web API服務的實現(xiàn)。

提供用戶數(shù)據(jù)的REST服務的實現(xiàn):

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

從上面代碼實現(xiàn)可以看出,User REST 服務依賴與IUserService接口,并且也沒有像傳統(tǒng)的方式將所有的業(yè)務邏輯放在Web API實現(xiàn)中,而是將具體的一些業(yè)務實現(xiàn)封裝到對應的應用層中,Rest API只負責調(diào)用對應的應用層中的服務。這樣設計好處有:

1.REST 服務部依賴與應用層接口,使得職責分離,將應用層服務的實例化交給單獨的依賴注入容器去完成,而REST服務只負責調(diào)用對應應用服務的方法來獲取數(shù)據(jù)。采用依賴接口而不依賴與具體類的實現(xiàn),使得類與類之間低耦合。

2.REST服務內(nèi)不包括具體的業(yè)務邏輯實現(xiàn)。這樣的設計可以使得服務更好地分離,如果你后期想用WCF來實現(xiàn)REST服務的,這樣就不需要重復在WCF的REST服務類中重復寫一篇Web API中的邏輯了,這時候完全可以調(diào)用應用服務的接口方法來實現(xiàn)WCF REST服務。所以將業(yè)務邏輯實現(xiàn)抽到應用服務層去實現(xiàn),這樣的設計將使得REST 服務職責更加單一,REST服務實現(xiàn)更容易擴展。

用戶應用服務的實現(xiàn):

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<UserDto> GetUsers(PageInput input)
    {
      var result = GetDefault<GetResults<UserDto>>();
      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<UpdateResult>();
      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<int> AddUser(UserDto userDto)
    {
      var result = GetDefault<CreateResult<int>>();
      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<DeleteResult>();
      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<UpdateResult>();
      var userEntity =_userRepository.FindSingle(x => x.Id == user.Id);
      if (userEntity == null)
      {
        result.Message = string.Format("當前編輯的用戶“{0}”已經(jīng)不存在", user.Name);
        return result;
      }
      userEntity.Password = user.Password;
      _userRepository.Commit();
      result.IsSaved = true;
      return result;
    }

    public GetResult<UserDto> GetUser(int userId)
    {
      var result = GetDefault<GetResult<UserDto>>();
      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<UpdateResult>();
      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<DeleteResult>();
      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<User, bool>> BuildExpression(PageInput pageInput)
    {
      Expression<Func<User, bool>> 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;
    }
  }

這里應用服務層其實還可以進一步的優(yōu)化,實現(xiàn)代碼層級的讀寫分離,定義IReadOnlyService接口和IWriteServie接口,并且把寫操作可以采用泛型方法的方式抽象到BaseService中去實現(xiàn)。這樣一些增刪改操作實現(xiàn)公用,之所以可以將這里操作實現(xiàn)公用,是因為這些操作都是非常類似的,無非是操作的實體不一樣罷了。

倉儲層的實現(xiàn):

用戶應用服務也沒有直接依賴與具體的倉儲類,同樣也是依賴其接口。對應的用戶倉儲類的實現(xiàn)如下:

public class BaseRepository<TEntity> : IRepository<TEntity>
    where TEntity :class , IEntity
  {
    private readonly ThreadLocal<UserManagerDBContext> _localCtx = new ThreadLocal<UserManagerDBContext>(() => new UserManagerDBContext());

    public UserManagerDBContext DbContext { get { return _localCtx.Value; } }

    public TEntity FindSingle(Expression<Func<TEntity, bool>> exp = null)
    {
      return DbContext.Set<TEntity>().AsNoTracking().FirstOrDefault(exp);
    }

    public IQueryable<TEntity> Find(Expression<Func<TEntity, bool>> exp = null)
    {
      return Filter(exp);
    }

    public IQueryable<TEntity> Find(Expression<Func<TEntity, bool>> expression, Expression<Func<TEntity, dynamic>> 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<TEntity>().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<TEntity, bool>> exp = null)
    {
      return Filter(exp).Count();
    }

    public void Add(TEntity entity)
    {
      DbContext.Set<TEntity>().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<TEntity>().Remove(entity);
    }

    public void Delete(ICollection<TEntity> entityCollection)
    {
      if(entityCollection.Count ==0)
        return;

      DbContext.Set<TEntity>().Attach(entityCollection.First());
      DbContext.Set<TEntity>().RemoveRange(entityCollection);
    }

    private IQueryable<TEntity> Filter(Expression<Func<TEntity, bool>> exp)
    {
      var dbSet = DbContext.Set<TEntity>().AsQueryable();
      if (exp != null)
        dbSet = dbSet.Where(exp);
      return dbSet;
    }

    public void Commit()
    {
      DbContext.SaveChanges();
    }
  }

public class UserRepository :BaseRepository<User>, IUserRepository
  {
     
  }

 四、AngularJS前端實現(xiàn)

Web前端的實現(xiàn)就是采用AngularJS來實現(xiàn),并且采用模塊化開發(fā)模式。具體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開發(fā)的Web應用程序的代碼之間的調(diào)用層次和后端基本一致,也是視圖頁面——》控制器模塊——》服務模塊——》Web API服務。

并且Web前端CSS和JS資源的加載采用了Bundle的方式來減少請求資源的次數(shù),從而加快頁面加載時間。具體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

<!DOCTYPE html>
<html ng-app="LH">
<head>
  <meta name="viewport" content="width=device-width" />
  <title>簡易權限管理系統(tǒng)Demo</title>
  @Styles.Render("~/js/base/style")
  @Scripts.Render("~/js/base/lib")
</head>
<body ng-controller="navigation">
  <nav class="navbar navbar-inverse navbar-fixed-top">
    <div class="container-fluid">
      <div class="navbar-header">
        <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
          <span class="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" href="/">簡易權限管理系統(tǒng)Demo</a>
      </div>
      <div class="navbar-collapse collapse">
        <ul class="nav navbar-nav navbar-left">
          <li class="{{item.isActive?'active':''}}" ng-repeat="item in ls">
            <a href="#{{item.urls[0].link}}">{{item.name}}</a>
          </li>
        </ul>
        <div class="navbar-form navbar-right">
          <a href="@Url.Action("UnLogin", "Home", null)" class="btn btn-danger">
            {{lang.exit}}
          </a>
        </div>
      </div>
    </div>
  </nav>
  <div class="container-fluid">
    <div class="row">
      <div class="col-sm-3 col-md-2 sidebar">
        <ul class="nav nav-sidebar">
          <li class="{{item.isActive?'active':''}}" ng-repeat="item in urls"><a href="#{{item.link}}">{{item.title}}</a></li>
        </ul>
      </div>
      <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
        <div ng-view></div>
      </div>
    </div>
  </div>
  @Scripts.Render("~/js/angularjs/app")
</body>
</html>

五、運行效果

介紹完前后端的實現(xiàn)之后,接下來讓我們看下整個項目的運行效果:

六、總結

到此,本文的所有內(nèi)容都介紹完了,盡管本文的AngularJS的應用項目還有很多完善的地方,例如沒有緩沖的支持、沒有實現(xiàn)讀寫分離,沒有對一些API進行壓力測試等。但AngularJS在實際項目中的應用基本是這樣的,大家如果在項目中有需要用到AngularJS,正好你們公司的后臺又是.NET的話,相信本文的分享可以是一個很好的參考。

本文所有源碼下載地址:PrivilegeManagement

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • Angular2平滑升級到Angular4的步驟詳解

    Angular2平滑升級到Angular4的步驟詳解

    最近Angular項目組終于發(fā)布了新版——正式版 Angular 4.0.0。所以想著就來嘗試下升級,記錄下整個升級過程分享給大家,所以這篇文章主要介紹了Angular2升級到Angular4的詳細步驟,需要的朋友可以參考下。
    2017-03-03
  • Angular應用程序的Hydration基本概念詳解

    Angular應用程序的Hydration基本概念詳解

    這篇文章主要為大家介紹了Angular應用程序的Hydration基本概念詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • Angular2中Bootstrap界面庫ng-bootstrap詳解

    Angular2中Bootstrap界面庫ng-bootstrap詳解

    不知道大家有沒有留意,最近angular-ui團隊終于正式發(fā)布了基于 Angular2的Bootstrap界面庫ng-bootstrap ,之前工作中一直在用 AngularJS 1.x 的UI Bootstrap , 因此對這個ng-bootstrap 也是很感興趣,所以第一時間進行試用。這篇文章就給大家詳細介紹下ng-bootstrap。
    2016-10-10
  • Angularjs單選改為多選的開發(fā)過程及問題解析

    Angularjs單選改為多選的開發(fā)過程及問題解析

    在項目中遇到這樣的需求想把下拉框的單選改為多選,怎么實現(xiàn)呢?下面小編通過本文給大家分享angularjs單選改為多選的開發(fā)過程及問題解析,需要的朋友參考下
    2017-02-02
  • 詳解Angular-ui-BootStrap組件的解釋以及使用

    詳解Angular-ui-BootStrap組件的解釋以及使用

    這篇文章主要介紹了詳解Angular-ui-BootStrap組件的解釋以及使用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • Angular.js與Bootstrap相結合實現(xiàn)表格分頁代碼

    Angular.js與Bootstrap相結合實現(xiàn)表格分頁代碼

    最近一直在學習angularjs相關知識,在學習過程中寫了一個小demo,下面把代碼思路分享給大家,感興趣的朋友一起學習
    2016-04-04
  • AngularJS中的作用域實例分析

    AngularJS中的作用域實例分析

    這篇文章主要介紹了AngularJS中的作用域,結合實例形式較為詳細的分析了AngularJS涉及作用域的相關問題與注意事項,需要的朋友可以參考下
    2018-05-05
  • 詳解AngularJS中ng-src指令的使用

    詳解AngularJS中ng-src指令的使用

    這篇文章給大家詳細介紹了AngularJS中ng-src指令的使用,對大家學習AngularJS具有一定參考價值,有需要的朋友們可以參考借鑒。
    2016-09-09
  • AngularJS實現(xiàn)動態(tài)編譯添加到dom中的方法

    AngularJS實現(xiàn)動態(tài)編譯添加到dom中的方法

    這篇文章主要介紹了AngularJS實現(xiàn)動態(tài)編譯添加到dom中的方法,結合實例形式分析了AngularJS動態(tài)編輯構建模板的相關操作技巧,需要的朋友可以參考下
    2016-11-11
  • Angular異步變同步處理方法

    Angular異步變同步處理方法

    今天小編就為大家分享一篇Angular異步變同步處理方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08

最新評論