AngularJS中的$resource服务相比$http服务更适合与RESTful服务进行交互。本篇后端使用ASP.NET Web API, 前端使用$resource,实现增删改查。

本系列包括:

1、前端使用AngularJS的$resource,后端ASP.NET Web API,实现增删改查
2、前端使用AngularJS的$resource,后端ASP.NET Web API,实现分页、过滤

领域和上下文

首先领域先行。

  1. public class StudentVm
  2. {
  3. [Key]
  4. public int Id { get; set; }
  5. public string Name { get; set; }
  6. public string Age { get; set; }
  7. }

上下文。

  1. public class StudentContext : DbContext
  2. {
  3. public StudentContext() : base("conn")
  4. {
  5. Database.SetInitializer(new StudentInitializer());
  6. }
  7.  
  8. public DbSet<StudentVm> Students { get; set; }
  9. }

上下文的构造函数中,StudentIntializer类对数据进行了初始化。

  1. public class StudentInitializer : CreateDatabaseIfNotExists<StudentContext>
  2. {
  3. protected override void Seed(StudentContext context)
  4. {
  5. IList<StudentVm> students = new List<StudentVm>();
  6. students.Add(new StudentVm() { Name = "aa", Age = "" });
  7. students.Add(new StudentVm() { Name = "bb", Age = "" });
  8. students.Add(new StudentVm() { Name = "cc", Age = "" });
  9. students.Add(new StudentVm() { Name = "dd", Age = "" });
  10. students.Add(new StudentVm() { Name = "ee", Age = "" });
  11. students.Add(new StudentVm() { Name = "ff", Age = "" });
  12. students.Add(new StudentVm() { Name = "gg", Age = "" });
  13.  
  14. foreach(StudentVm student in students)
  15. {
  16. context.Students.Add(student);
  17. }
  18.  
  19. base.Seed(context);
  20. }
  21. }

对于EF Code First来说,Web.config中需要配置连接字符串。

  1. <connectionStrings>
  2. <add name="conn"
  3. connectionString="Data Source=.;User=yourname;Password=yourpassword;Initial Catalog=StudentsDemo;Integrated Security=True"
  4. providerName="System.Data.SqlClient"/>
  5. </connectionStrings>

Repository

在这里使用上下文类,实现增删改查。

  1. public class StudentsReop
  2. {
  3. private StudentContext _db = new StudentContext();
  4.  
  5. public IEnumerable<StudentVm> Query()
  6. {
  7. return _db.Students;
  8. }
  9.  
  10. public StudentVm Get(int id)
  11. {
  12. return _db.Students.SingleOrDefault(s => s.Id == id);
  13. }
  14.  
  15. //更新
  16. public void Put(int id, StudentVm student)
  17. {
  18. var stu = _db.Students.SingleOrDefault(s => s.Id == id);
  19. _db.Students.Attach(stu);
  20. _db.Entry(stu).State = System.Data.Entity.EntityState.Modified;
  21. _db.Entry(stu).CurrentValues.SetValues(student);
  22. _db.SaveChanges();
  23. }
  24.  
  25. //添加
  26. public void Post(StudentVm student)
  27. {
  28. _db.Students.Add(student);
  29. _db.SaveChanges();
  30. }
  31.  
  32. public void Delete(int id)
  33. {
  34. var student = _db.Students.SingleOrDefault(s => s.Id.Equals(id));
  35. _db.Students.Remove(student);
  36. bool saveFailed;
  37. do
  38. {
  39. saveFailed = false;
  40.  
  41. try
  42. {
  43. _db.SaveChanges();
  44. }
  45. catch (DbUpdateConcurrencyException ex)
  46. {
  47. saveFailed = true;
  48.  
  49. //重新加载数据库中的实体,使之处于unchanged的状态
  50. ex.Entries.Single().Reload();
  51. }
  52. } while (saveFailed);
  53. }
  54. }

API控制器

  1. public class StudentsController : ApiController
  2. {
  3. private StudentsReop _reop = new StudentsReop();
  4.  
  5. //GET api/Students
  6. public HttpResponseMessage Get()
  7. {
  8. var students = _reop.Query().ToList();
  9. return Request.CreateResponse(HttpStatusCode.OK, students);
  10. }
  11.  
  12. //GET api/Students/5
  13. public HttpResponseMessage Get(int id)
  14. {
  15. var student = _reop.Get(id);
  16. return Request.CreateResponse(HttpStatusCode.OK, student);
  17. }
  18.  
  19. //POST api/Students
  20. public void Post([FromBody]StudentVm student)
  21. {
  22. _reop.Post(student);
  23. }
  24.  
  25. //PUT api/Students/5
  26. public void Put(int id, [FromBody]StudentVm student)
  27. {
  28. _reop.Put(id, student);
  29. }
  30.  
  31. //DELETE api/Students
  32. public void Delete(int id)
  33. {
  34. _reop.Delete(id);
  35. }
  36. }

允许跨域访问

默认情况下,ASP.NET Web API是不支持跨域访问的。为了支持,需要安装Microsoft.AspNet.WebApi.Cors。安装之后,需要在全局配置生效。在WepApiConfig.cs中配置如下:

  1. public static class WebApiConfig
  2. {
  3. public static void Register(HttpConfiguration config)
  4. {
  5. // Web API 配置和服务
  6.  
  7. // Web API 路由
  8. config.MapHttpAttributeRoutes();
  9.  
  10. config.EnableCors(new EnableCorsAttribute("*", "*", "*"));
  11.  
  12. config.Routes.MapHttpRoute(
  13. name: "DefaultApi",
  14. routeTemplate: "api/{controller}/{id}",
  15. defaults: new { id = RouteParameter.Optional }
  16. );
  17. }
  18. }

在本地,浏览器中:http://localhost:49621/api/Students

前端准备

后端完成,前端在WebStorm下安装先安装需要的几个插件:

  1. npm install angular
    npm install angular-route
    npm install angular-resource
    npm install angular-cookies
    npm install alertify
  2.  
  3. 再来了解下前端的文件结构:
  4.  
  5. app.js module,路由都在这里配置
    index.html 主视图,引用所有的css,js文件,提供让其它部分视图呈现的一块区域<div ng-view></div>
    .....service/ 自定义服务,$resouce的核心就封装在这里
    ..........studentService.js
    .....controller/
    ..........studentsCtrl.js 列表
    ..........studentUpdateCtrl.js 更新
    ..........studentCreateCtrl.js 添加
    .....views/
    ..........Students.html 列表
    ..........StudentInfo.html 更新
    ..........StudentCreate.html 添加
  6.  

index.html

  1.  
  1. <!DOCTYPE html>
  2. <html lang="en" ng-app="studentManagement">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>{{title}}</title>
  6. <link rel="stylesheet" href="node_modules/alertify/themes/alertify.core.css"/>
  7. </head>
  8. <body>
  9. <div>
  10. <p>
  11. <a href="#/">Students</a>
  12. &nbsp;&nbsp;
  13. <a href="#/Create">Create Student</a>
  14. </p>
  15. </div>
  16.  
  17. <div ng-view></div>
  18.  
  19. <script src="node_modules/angular/angular.min.js"></script>
  20. <script src="node_modules/angular-route/angular-route.min.js"></script>
  21. <script src="node_modules/angular-resource/angular-resource.min.js"></script>
  22. <script src="node_modules/angular-cookies/angular-cookies.min.js"></script>
  23. <script src="node_modules/alertify/lib/alertify.min.js"></script>
  24.  
  25. <script src="app.js"></script>
  26.  
  27. <script src="service/studentService.js"></script>
  28. <script src="controller/studentUpdateCtrl.js"></script>
  29. <script src="controller/studentsCtrl.js"></script>
  30. <script src="controller/studentCreateCtrl.js"></script>
  31.  
  32. </body>
  33. </html>

以上,主视图中,需要注意引用js文件的顺序,一般angualr相关方在最上面,然后app对应js文件,最后是各种服务和控制器相关js文件。

app.js

在这里,当然首先要定义一个module,定义module的时候要把所有用到的module依赖写在module方法的第二个实参里。还有一个主项工作就是定义设置路由,而且,如果想让以后视同从controller中拿数据更快,我们还可以利用路由的resolve机制,把数据从某处读取出来,先放到路由中,然后在controller中把resolve机制下的数据读出来。

  1. "use strict";
  2.  
  3. var studentsManagement = angular.module("studentManagement",["ngResource","ngCookies","ngRoute"])
  4. .run(function($rootScope){
  5. $rootScope.title = "Home";
  6. })
  7. .config(["$routeProvider","$locationProvider", function($routeProvider, $locationProvider){
  8.  
  9. //关于url的基本配置
  10. //$locationProvider.html5Mode({
  11. // enabled: true,
  12. // requireBase: false
  13. //});
  14.  
  15. //配置路由
  16. $routeProvider.when("/", {
  17. templateUrl: "views/Students.html",
  18. controller: "studentsCtrl",
  19. resolve: {
  20. students: function($q,studentDataService){
  21.  
  22. //$q异步执行方法
  23. var deferred = $q.defer();
  24. studentDataService.query(function(data){
  25. deferred.resolve(data);
  26. });
  27.  
  28. return deferred.promise;
  29. }
  30. }
  31. }).when("/Student/:id",{
  32. templateUrl: "views/StudentInfo.html",
  33. controller: "studentUpdateCtrl",
  34. resolve: {
  35. student: function($q, studentDataService, $route){
  36. var defered = $q.defer();
  37.  
  38. //从路由中获取id的值
  39. var id = $route.current.params.id;
  40.  
  41. studentDataService.get({id: id}, function(data){
  42. defered.resolve(data);
  43. });
  44.  
  45. return defered.promise;
  46. }
  47. }
  48. }).when("/Create",{
  49. templateUrl: "views/CreateStudent.html",
  50. controller: "studentCreateCtrl"
  51. });
  52.  
  53. }]);

● 使用$routeProvider配置路由的过程就是让一对对view和controller结婚的过程

● 显示列表的时候通过路由的resolve机制把数据先放在了路由中

● 显示某个Sudent的时候也通过路由的resolve机制把数据先放在了路由中

●/Student/:id这个路由格式中的id代表变量,可借助$route服务从路由中取出来var id = $route.current.params.id;

studentService.js

在这里,封装了对API的所有请求。

而$resource服务是位于angular-resource中,大致按如下调用:

$resource(url,{paramDefaults},{actions},{options});

其中,第一个参数是必须的,其它都optional。

  1. angular.module('studentManagement').factory("studentDataService",["$resource", function($resource){
  2.  
  3. var baseUrl = "http://localhost:49621/api/Students";
  4. return $resource("http://localhost:49621/api/Students",{},{
  5. query: {method: "GET", isArray: true },
  6. create: {method: "POST"},
  7. get: {method: "GET", url: baseUrl + "?id=:id"},
  8. remove: {method: "DELETE", url: baseUrl + "?id=:id"},
  9. update: {method: "PUT", url: baseUrl + "?id=:id"}
  10. })
  11. }]);

以上,在"?id=:id"中,冒号后面的id是一个变量,在controller中通过对象传递到这里来,比如 studentDataService.remove({id: id}).$promise.then(...)

列表,studentsCtr.j和views/Students.html这对恋人

studentsCtr.js:

  1. angular.module('studentManagement').controller("studentsCtrl",['$scope','$route','$rootScope','studentDataService', function($scope,$route, $rootScope, studentDataService){
  2. $rootScope.title = "Students";
  3. $scope.students = $route.current.locals.students;//students在路由resolve中定义
  4. $scope.removeStudent = function(id, student){
  5. studentDataService.remove({id: id}).$promise.then(function(){
  6. //获取student在当前集合中的索引
  7. var index = $scope.students.indexOf(student);
  8. $scope.students.splice(index, 1);
  9. alertify.log(student.Name + ' is removed');
  10. });
  11. };
  12.  
  13. }]);

以上,students的数据并没有向那个源头发出请求获取,而是直接使用$route服务,把路由resolve机制中的变量值取了出来。删除数据实际是做2件事,一件是删除服务端的数据,一件是删除model中的数据。

Students.html:

  1. <table>
  2. <thead>
  3. <tr>
  4. <th>Name</th><th>Age</th><th>Actions</th>
  5. </tr>
  6. </thead>
  7. <tbody>
  8. <tr ng-repeat="student in students">
  9. <td>{{student.Name}}</td>
  10. <td>{{student.Age}}</td>
  11. <td>
  12. <a href="#/Student/{{student.Id}}">更新</a>
  13. &nbsp;&nbsp;
  14. <a href="javascript:void(0)" ng-click="$parent.removeStudent(student.Id, student)">移除</a>
  15. </td>
  16. </tr>
  17. </tbody>
  18. </table>

添加,studentCreateCtrl.js和views/CreateStudent.html这对恋人

studentCreateCtrl.js:

  1. angular.module('studentManagement').controller("studentCreateCtrl", ["$scope", "studentDataService", '$rootScope', "$location", function ($scope, studentDataService, $rootScope, $location) {
  2. $rootScope.title = "Create student";
  3.  
  4. $scope.saveStudent = function (student) {
  5. studentDataService.create(student).$promise.then(function (res) {
  6. $location.path('/');
  7. });
  8. };
  9. }]);

CreateStudent.html:

  1. <form>
  2. <input id="userName" ng-model="student.Name" />
  3. <br/>
  4. <input id="userAge" ng-model="student.Age" />
  5. <br/>
  6. <button ng-click="saveStudent(student)">Save</button>
  7. <button type="reset">Cancel</button>
  8. </form>

更新,studentUpdateCtrl.js和views/StudentInfo.html这对恋人

studentUpdateCtrl.js:

  1. angular.module('studentManagement').controller("studentUpdateCtrl",["$scope","$route","$rootScope","studentDataService","$location", function($scope,$route, $rootScope, studentDataService, $location){
  2.  
  3. //student是在resolve中定义的
  4. $scope.student = $route.current.locals.student;
  5. $rootScope.title = "Student Info -" + $scope.student.Name;
  6. $scope.updateInfo = function(student){
  7. studentDataService.update({id: student.Id}, student).$promise.then(function(){
  8. $location.url("/");
  9. alertify.log("Updated Student Scucess");
  10. });
  11. };
  12. }]);

StudentInfo.html:

  1. <form>
  2. <input type="text" id="userName" ng-model="student.Name"/>
  3. <br/>
  4. <input type="text" id="userAge" ng-model="student.Age"/>
  5. <br/>
  6. <button ng-click="updateInfo(student)">Update</button>
  7. <button type="reset">Reset</button>
  8. </form>

待续~~

前端使用AngularJS的$resource,后端ASP.NET Web API,实现增删改查的更多相关文章

  1. 前端使用AngularJS的$resource,后端ASP.NET Web API,实现分页、过滤

    在上一篇中实现了增删改查,本篇实现分页和过滤. 本系列包括: 1.前端使用AngularJS的$resource,后端ASP.NET Web API,实现增删改查2.前端使用AngularJS的$re ...

  2. AngularJS使用OData请求ASP.NET Web API资源的思路

    本篇整理AngularJS使用OData请求ASP.NET Web API资源的思路. 首先给ASP.NET Web API插上OData的翅膀,通过NuGet安装OData. 然后,给control ...

  3. AngularJS中使用$http对MongoLab数据表进行增删改查

    本篇体验使用AngularJS中的$http对MongoLab数据表进行增删改查. 主页面: <button ng-click="loadCourse()">Load ...

  4. Asp.Net操作MySql数据库增删改查

    Asp.Net操作MySql数据库增删改查,话不多说直接步入正题.git源码地址:https://git.oschina.net/gxiaopan/NetMySql.git  1.安装MySQL数据库 ...

  5. 【ASP.NET MVC】jqGrid 增删改查详解

    1   概述 本篇文章主要是关于JqGrid的,主要功能包括使用JqGrid增删查改,导入导出,废话不多说,直接进入正题. 2   Demo相关 2.1   Demo展示 第一部分 第二部分 2.2 ...

  6. 前端AngularJS后端ASP.NET Web API上传文件

    本篇体验使用AngularJS向后端ASP.NET API控制器上传文件.    首先服务端: public class FilesController : ApiController { //usi ...

  7. ASP连接access 数据库的增删改查 - imsoft.cnblogs

    假设数据库文件名叫data.mdb里面有2个表:1.admin2.news假设admin是保存用户名和密码,里面有字段:UserName,PassWord.假设我们要在判断一个用户名叫name,密码是 ...

  8. asp.net mvc4 easyui datagrid 增删改查分页 导出 先上传后导入 NPOI批量导入 导出EXCEL

    效果图 数据库代码 create database CardManage use CardManage create table CardManage ( ID ,) primary key, use ...

  9. asp.net EasyUI DataGrid 实现增删改查

    转自:http://www.cnblogs.com/create/p/3410314.html 前台代码: <!DOCTYPE html> <html xmlns="htt ...

随机推荐

  1. 【网络编程】使用getnameinfo()/getaddrinfo()/InetPton()

    1.简要 从前用的网络编程函数现在又做了一定的改动,报了这么3个错误. error C4996: 'inet_ntoa': Use inet_ntop() or InetNtop() instead ...

  2. lvs+keepalived+nginx实现高性能负载均衡集群【转】

    转自 lvs+keepalived+nginx实现高性能负载均衡集群 - 青衫lys - 博客园http://www.cnblogs.com/liuyisai/p/5990645.html 一.为什么 ...

  3. WEBAPI 帖子收藏

    [翻译]ASP.NET Web API入门 [翻译]ASP.NET WEB API异常处理 ASP.NET WebAPI 路由规则与POST数据 ASP.NET Web API路由规则(二) ASP. ...

  4. 测试开发之Django——No2.Django的安装以及项目创建

    开发平台:Mac Python版本:3.7 Django版本:2.0.5 一.Django的安装 1.pip安装 输入命令pip install Django==2.0.5 说明:不指定版本,则安装的 ...

  5. PHP 5.2、5.3、5.4、5.5、5.6 对比以及功能详解

    php5.2.x php5.3.x php5.4.x php5.5.x php5.6.x 对比详解 截至目前(2014.2), PHP 的最新稳定版本是 PHP5.5, 但有差不多一半的用户仍在使用已 ...

  6. JavaScript中的普通函数与构造函数

    问题 什么是构造函数? 构造函数与普通函数区别是什么? 用new关键字的时候到底做了什么? 构造函数有返回值怎么办? 构造函数能当普通函数调用吗? 以下是我的一些理解,理解错误的地方恳请大家帮忙指正, ...

  7. MVC中使用Web API和EntityFramework

    在ASP.NET MVC中使用Web API和EntityFramework构建应用程序   最近做了一个项目技术预研:在ASP.NET MVC框架中使用Web API和EntityFramework ...

  8. Storm程序的并发机制(重点掌握)

    概念 Workers (JVMs): 在一个物理节点上可以运行一个或多个独立的JVM 进程.一个Topology可以包含一个或多个worker(并行的跑在不同的物理机上), 所以worker proc ...

  9. Java 分布式系统 实现session共享

    当然业界已经有很多成熟的解决方案,我罗列如下: 1.服务器实现的session复制或session共享,这类型的共享session是和服务器紧密相关的,比如webSphere或JBOSS在搭建集群时候 ...

  10. ArduinoYun教程之Arduino环境与Linux环境的桥梁Bridge

    ArduinoYun教程之Arduino环境与Linux环境的桥梁Bridge Arduino环境与Linux环境的桥梁——Bridge 在第一章中介绍Arduino Yun硬件的时候提到过,它上面有 ...