前端使用AngularJS的$resource,后端ASP.NET Web API,实现增删改查
AngularJS中的$resource服务相比$http服务更适合与RESTful服务进行交互。本篇后端使用ASP.NET Web API, 前端使用$resource,实现增删改查。
本系列包括:
1、前端使用AngularJS的$resource,后端ASP.NET Web API,实现增删改查
2、前端使用AngularJS的$resource,后端ASP.NET Web API,实现分页、过滤
领域和上下文
首先领域先行。
- public class StudentVm
- {
- [Key]
- public int Id { get; set; }
- public string Name { get; set; }
- public string Age { get; set; }
- }
上下文。
- public class StudentContext : DbContext
- {
- public StudentContext() : base("conn")
- {
- Database.SetInitializer(new StudentInitializer());
- }
- public DbSet<StudentVm> Students { get; set; }
- }
上下文的构造函数中,StudentIntializer类对数据进行了初始化。
- public class StudentInitializer : CreateDatabaseIfNotExists<StudentContext>
- {
- protected override void Seed(StudentContext context)
- {
- IList<StudentVm> students = new List<StudentVm>();
- students.Add(new StudentVm() { Name = "aa", Age = "" });
- students.Add(new StudentVm() { Name = "bb", Age = "" });
- students.Add(new StudentVm() { Name = "cc", Age = "" });
- students.Add(new StudentVm() { Name = "dd", Age = "" });
- students.Add(new StudentVm() { Name = "ee", Age = "" });
- students.Add(new StudentVm() { Name = "ff", Age = "" });
- students.Add(new StudentVm() { Name = "gg", Age = "" });
- foreach(StudentVm student in students)
- {
- context.Students.Add(student);
- }
- base.Seed(context);
- }
- }
对于EF Code First来说,Web.config中需要配置连接字符串。
- <connectionStrings>
- <add name="conn"
- connectionString="Data Source=.;User=yourname;Password=yourpassword;Initial Catalog=StudentsDemo;Integrated Security=True"
- providerName="System.Data.SqlClient"/>
- </connectionStrings>
Repository
在这里使用上下文类,实现增删改查。
- public class StudentsReop
- {
- private StudentContext _db = new StudentContext();
- public IEnumerable<StudentVm> Query()
- {
- return _db.Students;
- }
- public StudentVm Get(int id)
- {
- return _db.Students.SingleOrDefault(s => s.Id == id);
- }
- //更新
- public void Put(int id, StudentVm student)
- {
- var stu = _db.Students.SingleOrDefault(s => s.Id == id);
- _db.Students.Attach(stu);
- _db.Entry(stu).State = System.Data.Entity.EntityState.Modified;
- _db.Entry(stu).CurrentValues.SetValues(student);
- _db.SaveChanges();
- }
- //添加
- public void Post(StudentVm student)
- {
- _db.Students.Add(student);
- _db.SaveChanges();
- }
- public void Delete(int id)
- {
- var student = _db.Students.SingleOrDefault(s => s.Id.Equals(id));
- _db.Students.Remove(student);
- bool saveFailed;
- do
- {
- saveFailed = false;
- try
- {
- _db.SaveChanges();
- }
- catch (DbUpdateConcurrencyException ex)
- {
- saveFailed = true;
- //重新加载数据库中的实体,使之处于unchanged的状态
- ex.Entries.Single().Reload();
- }
- } while (saveFailed);
- }
- }
API控制器
- public class StudentsController : ApiController
- {
- private StudentsReop _reop = new StudentsReop();
- //GET api/Students
- public HttpResponseMessage Get()
- {
- var students = _reop.Query().ToList();
- return Request.CreateResponse(HttpStatusCode.OK, students);
- }
- //GET api/Students/5
- public HttpResponseMessage Get(int id)
- {
- var student = _reop.Get(id);
- return Request.CreateResponse(HttpStatusCode.OK, student);
- }
- //POST api/Students
- public void Post([FromBody]StudentVm student)
- {
- _reop.Post(student);
- }
- //PUT api/Students/5
- public void Put(int id, [FromBody]StudentVm student)
- {
- _reop.Put(id, student);
- }
- //DELETE api/Students
- public void Delete(int id)
- {
- _reop.Delete(id);
- }
- }
允许跨域访问
默认情况下,ASP.NET Web API是不支持跨域访问的。为了支持,需要安装Microsoft.AspNet.WebApi.Cors。安装之后,需要在全局配置生效。在WepApiConfig.cs中配置如下:
- public static class WebApiConfig
- {
- public static void Register(HttpConfiguration config)
- {
- // Web API 配置和服务
- // Web API 路由
- config.MapHttpAttributeRoutes();
- config.EnableCors(new EnableCorsAttribute("*", "*", "*"));
- config.Routes.MapHttpRoute(
- name: "DefaultApi",
- routeTemplate: "api/{controller}/{id}",
- defaults: new { id = RouteParameter.Optional }
- );
- }
- }
在本地,浏览器中:http://localhost:49621/api/Students
前端准备
后端完成,前端在WebStorm下安装先安装需要的几个插件:
- npm install angular
npm install angular-route
npm install angular-resource
npm install angular-cookies
npm install alertify- 再来了解下前端的文件结构:
- 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 添加
index.html
- <!DOCTYPE html>
- <html lang="en" ng-app="studentManagement">
- <head>
- <meta charset="UTF-8">
- <title>{{title}}</title>
- <link rel="stylesheet" href="node_modules/alertify/themes/alertify.core.css"/>
- </head>
- <body>
- <div>
- <p>
- <a href="#/">Students</a>
-
- <a href="#/Create">Create Student</a>
- </p>
- </div>
- <div ng-view></div>
- <script src="node_modules/angular/angular.min.js"></script>
- <script src="node_modules/angular-route/angular-route.min.js"></script>
- <script src="node_modules/angular-resource/angular-resource.min.js"></script>
- <script src="node_modules/angular-cookies/angular-cookies.min.js"></script>
- <script src="node_modules/alertify/lib/alertify.min.js"></script>
- <script src="app.js"></script>
- <script src="service/studentService.js"></script>
- <script src="controller/studentUpdateCtrl.js"></script>
- <script src="controller/studentsCtrl.js"></script>
- <script src="controller/studentCreateCtrl.js"></script>
- </body>
- </html>
以上,主视图中,需要注意引用js文件的顺序,一般angualr相关方在最上面,然后app对应js文件,最后是各种服务和控制器相关js文件。
app.js
在这里,当然首先要定义一个module,定义module的时候要把所有用到的module依赖写在module方法的第二个实参里。还有一个主项工作就是定义设置路由,而且,如果想让以后视同从controller中拿数据更快,我们还可以利用路由的resolve机制,把数据从某处读取出来,先放到路由中,然后在controller中把resolve机制下的数据读出来。
- "use strict";
- var studentsManagement = angular.module("studentManagement",["ngResource","ngCookies","ngRoute"])
- .run(function($rootScope){
- $rootScope.title = "Home";
- })
- .config(["$routeProvider","$locationProvider", function($routeProvider, $locationProvider){
- //关于url的基本配置
- //$locationProvider.html5Mode({
- // enabled: true,
- // requireBase: false
- //});
- //配置路由
- $routeProvider.when("/", {
- templateUrl: "views/Students.html",
- controller: "studentsCtrl",
- resolve: {
- students: function($q,studentDataService){
- //$q异步执行方法
- var deferred = $q.defer();
- studentDataService.query(function(data){
- deferred.resolve(data);
- });
- return deferred.promise;
- }
- }
- }).when("/Student/:id",{
- templateUrl: "views/StudentInfo.html",
- controller: "studentUpdateCtrl",
- resolve: {
- student: function($q, studentDataService, $route){
- var defered = $q.defer();
- //从路由中获取id的值
- var id = $route.current.params.id;
- studentDataService.get({id: id}, function(data){
- defered.resolve(data);
- });
- return defered.promise;
- }
- }
- }).when("/Create",{
- templateUrl: "views/CreateStudent.html",
- controller: "studentCreateCtrl"
- });
- }]);
● 使用$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。
- angular.module('studentManagement').factory("studentDataService",["$resource", function($resource){
- var baseUrl = "http://localhost:49621/api/Students";
- return $resource("http://localhost:49621/api/Students",{},{
- query: {method: "GET", isArray: true },
- create: {method: "POST"},
- get: {method: "GET", url: baseUrl + "?id=:id"},
- remove: {method: "DELETE", url: baseUrl + "?id=:id"},
- update: {method: "PUT", url: baseUrl + "?id=:id"}
- })
- }]);
以上,在"?id=:id"中,冒号后面的id是一个变量,在controller中通过对象传递到这里来,比如 studentDataService.remove({id: id}).$promise.then(...)
列表,studentsCtr.j和views/Students.html这对恋人
studentsCtr.js:
- angular.module('studentManagement').controller("studentsCtrl",['$scope','$route','$rootScope','studentDataService', function($scope,$route, $rootScope, studentDataService){
- $rootScope.title = "Students";
- $scope.students = $route.current.locals.students;//students在路由resolve中定义
- $scope.removeStudent = function(id, student){
- studentDataService.remove({id: id}).$promise.then(function(){
- //获取student在当前集合中的索引
- var index = $scope.students.indexOf(student);
- $scope.students.splice(index, 1);
- alertify.log(student.Name + ' is removed');
- });
- };
- }]);
以上,students的数据并没有向那个源头发出请求获取,而是直接使用$route服务,把路由resolve机制中的变量值取了出来。删除数据实际是做2件事,一件是删除服务端的数据,一件是删除model中的数据。
Students.html:
- <table>
- <thead>
- <tr>
- <th>Name</th><th>Age</th><th>Actions</th>
- </tr>
- </thead>
- <tbody>
- <tr ng-repeat="student in students">
- <td>{{student.Name}}</td>
- <td>{{student.Age}}</td>
- <td>
- <a href="#/Student/{{student.Id}}">更新</a>
-
- <a href="javascript:void(0)" ng-click="$parent.removeStudent(student.Id, student)">移除</a>
- </td>
- </tr>
- </tbody>
- </table>
添加,studentCreateCtrl.js和views/CreateStudent.html这对恋人
studentCreateCtrl.js:
- angular.module('studentManagement').controller("studentCreateCtrl", ["$scope", "studentDataService", '$rootScope', "$location", function ($scope, studentDataService, $rootScope, $location) {
- $rootScope.title = "Create student";
- $scope.saveStudent = function (student) {
- studentDataService.create(student).$promise.then(function (res) {
- $location.path('/');
- });
- };
- }]);
CreateStudent.html:
- <form>
- <input id="userName" ng-model="student.Name" />
- <br/>
- <input id="userAge" ng-model="student.Age" />
- <br/>
- <button ng-click="saveStudent(student)">Save</button>
- <button type="reset">Cancel</button>
- </form>
更新,studentUpdateCtrl.js和views/StudentInfo.html这对恋人
studentUpdateCtrl.js:
- angular.module('studentManagement').controller("studentUpdateCtrl",["$scope","$route","$rootScope","studentDataService","$location", function($scope,$route, $rootScope, studentDataService, $location){
- //student是在resolve中定义的
- $scope.student = $route.current.locals.student;
- $rootScope.title = "Student Info -" + $scope.student.Name;
- $scope.updateInfo = function(student){
- studentDataService.update({id: student.Id}, student).$promise.then(function(){
- $location.url("/");
- alertify.log("Updated Student Scucess");
- });
- };
- }]);
StudentInfo.html:
- <form>
- <input type="text" id="userName" ng-model="student.Name"/>
- <br/>
- <input type="text" id="userAge" ng-model="student.Age"/>
- <br/>
- <button ng-click="updateInfo(student)">Update</button>
- <button type="reset">Reset</button>
- </form>
待续~~
前端使用AngularJS的$resource,后端ASP.NET Web API,实现增删改查的更多相关文章
- 前端使用AngularJS的$resource,后端ASP.NET Web API,实现分页、过滤
在上一篇中实现了增删改查,本篇实现分页和过滤. 本系列包括: 1.前端使用AngularJS的$resource,后端ASP.NET Web API,实现增删改查2.前端使用AngularJS的$re ...
- AngularJS使用OData请求ASP.NET Web API资源的思路
本篇整理AngularJS使用OData请求ASP.NET Web API资源的思路. 首先给ASP.NET Web API插上OData的翅膀,通过NuGet安装OData. 然后,给control ...
- AngularJS中使用$http对MongoLab数据表进行增删改查
本篇体验使用AngularJS中的$http对MongoLab数据表进行增删改查. 主页面: <button ng-click="loadCourse()">Load ...
- Asp.Net操作MySql数据库增删改查
Asp.Net操作MySql数据库增删改查,话不多说直接步入正题.git源码地址:https://git.oschina.net/gxiaopan/NetMySql.git 1.安装MySQL数据库 ...
- 【ASP.NET MVC】jqGrid 增删改查详解
1 概述 本篇文章主要是关于JqGrid的,主要功能包括使用JqGrid增删查改,导入导出,废话不多说,直接进入正题. 2 Demo相关 2.1 Demo展示 第一部分 第二部分 2.2 ...
- 前端AngularJS后端ASP.NET Web API上传文件
本篇体验使用AngularJS向后端ASP.NET API控制器上传文件. 首先服务端: public class FilesController : ApiController { //usi ...
- ASP连接access 数据库的增删改查 - imsoft.cnblogs
假设数据库文件名叫data.mdb里面有2个表:1.admin2.news假设admin是保存用户名和密码,里面有字段:UserName,PassWord.假设我们要在判断一个用户名叫name,密码是 ...
- asp.net mvc4 easyui datagrid 增删改查分页 导出 先上传后导入 NPOI批量导入 导出EXCEL
效果图 数据库代码 create database CardManage use CardManage create table CardManage ( ID ,) primary key, use ...
- asp.net EasyUI DataGrid 实现增删改查
转自:http://www.cnblogs.com/create/p/3410314.html 前台代码: <!DOCTYPE html> <html xmlns="htt ...
随机推荐
- 【网络编程】使用getnameinfo()/getaddrinfo()/InetPton()
1.简要 从前用的网络编程函数现在又做了一定的改动,报了这么3个错误. error C4996: 'inet_ntoa': Use inet_ntop() or InetNtop() instead ...
- lvs+keepalived+nginx实现高性能负载均衡集群【转】
转自 lvs+keepalived+nginx实现高性能负载均衡集群 - 青衫lys - 博客园http://www.cnblogs.com/liuyisai/p/5990645.html 一.为什么 ...
- WEBAPI 帖子收藏
[翻译]ASP.NET Web API入门 [翻译]ASP.NET WEB API异常处理 ASP.NET WebAPI 路由规则与POST数据 ASP.NET Web API路由规则(二) ASP. ...
- 测试开发之Django——No2.Django的安装以及项目创建
开发平台:Mac Python版本:3.7 Django版本:2.0.5 一.Django的安装 1.pip安装 输入命令pip install Django==2.0.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, 但有差不多一半的用户仍在使用已 ...
- JavaScript中的普通函数与构造函数
问题 什么是构造函数? 构造函数与普通函数区别是什么? 用new关键字的时候到底做了什么? 构造函数有返回值怎么办? 构造函数能当普通函数调用吗? 以下是我的一些理解,理解错误的地方恳请大家帮忙指正, ...
- MVC中使用Web API和EntityFramework
在ASP.NET MVC中使用Web API和EntityFramework构建应用程序 最近做了一个项目技术预研:在ASP.NET MVC框架中使用Web API和EntityFramework ...
- Storm程序的并发机制(重点掌握)
概念 Workers (JVMs): 在一个物理节点上可以运行一个或多个独立的JVM 进程.一个Topology可以包含一个或多个worker(并行的跑在不同的物理机上), 所以worker proc ...
- Java 分布式系统 实现session共享
当然业界已经有很多成熟的解决方案,我罗列如下: 1.服务器实现的session复制或session共享,这类型的共享session是和服务器紧密相关的,比如webSphere或JBOSS在搭建集群时候 ...
- ArduinoYun教程之Arduino环境与Linux环境的桥梁Bridge
ArduinoYun教程之Arduino环境与Linux环境的桥梁Bridge Arduino环境与Linux环境的桥梁——Bridge 在第一章中介绍Arduino Yun硬件的时候提到过,它上面有 ...