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>
&nbsp;&nbsp;
<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>
&nbsp;&nbsp;
<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,实现增删改查的更多相关文章

  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. MySQL乱码问题以及utf8mb4字符集

    MySQL乱码问题以及utf8mb4字符集 1.乱码 推荐大家看 深入MySQL字符集设置 ,区分检查client端.server端的编码:最简单暴力的方式,是在所有的环节都显式明确的指定相同的编码, ...

  2. 20175225《java程序设计》第五周学习总结

    20175225 2018-2019-2 <Java程序设计>第5周学习总结 教材学习内容总结 1.接口体中包含常量的声明(没有变量)和抽象方法两部分.接口体中只有抽象方法,没有普通的方法 ...

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

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

  4. VS Code折腾记 - (4) 常用必备插件推荐【前端】

    前言 这篇文章只要让你做一些基础的配置,把vscode变得更加顺手: 插件的需求不是一成不变,有些插件我已经移除了..在最新的VSCODE 1.9.1中, 部分以前用插件实现的功能已经集成了,那就没有 ...

  5. Android多开/分身检测

    原文:https://blog.darkness463.top/2018/05/04/Android-Virtual-Check/ 多开/分身原本用于方便有多个微信/QQ解决同时登录的问题,但近来年被 ...

  6. 【AtCoder】ARC087

    C - Good Sequence 题解 用个map愉悦一下就好了 代码 #include <bits/stdc++.h> #define fi first #define se seco ...

  7. 【GOF23设计模式】--工厂模式

    工厂模式: 实现了创建者调用者的分离 详细分类: 简单工厂模式 工厂方法模式 抽象工厂模式 面向对象设计的基本原则: OCP(开闭原则,Open-Closed Principle):一个软件的实体应当 ...

  8. 【Java】 大话数据结构(1) 线性表之顺序存储结构

     本文根据<大话数据结构>一书,实现了Java版的顺序存储结构. 顺序存储结构指的是用一段地址连续的存储单元一次存储线性表的数据元素,一般用一维数组来实现. 书中的线性表抽象数据类型定义如 ...

  9. sql 多表查询结果验证

    1.笛卡尔积 定义: 设A,B为集合,用A中元素为第一元素,B中元素为第二元素构成的有序对,所有这样的有序对组成的集合 ,叫做A与B的笛卡尔积,记作AxB. 上面有一个很关键的词为“有序”,因此,我们 ...

  10. 002.Rsync详细配置项

    一 相关参数 全局参数 在文件中[module]之前的所有参数都是全局参数,当然也可以在全局参数部分定义模块参数,这时候该参数的值就是所有模块的默认值. port 指定后台程序使用的端口号,默认为87 ...