对一个前端AngularJS,后端OData,ASP.NET Web API案例的理解
依然chsakell,他写了一篇前端AngularJS,后端OData,ASP.NET Web API的Demo,关于OData在ASP.NET Web API中的正删改查没有什么特别之处,但在前端调用API时,把各种调用使用$resouce封装在一个服务中的写法颇有借鉴意义。
文章:http://chsakell.com/2015/04/04/asp-net-web-api-feat-odata/
源码:https://github.com/chsakell/odatawebapi
首先是领域模型。
public class Employee
{
public int ID{get;set;} ...
public int AddressID { get; set; }
public virtual Address Address { get; set; } public int CompanyID { get; set; }
public virtual Company Company { get; set; }
} public class Address
{
public int ID{get;set;}
...
} public class Company
{
public int ID{get;set;} ..
public virtual List<Employee> Employees{get;set;} public Compay()
{
Employees = new List<Employee>();
}
}
使用EF Fuent API对领域进行配置,继承EntityTypeConfiguration<T>,比如:
public class CompanyConfiguration: EntityTypeConfiguration<Company>
{ }
上下文继承DbContext。
public class EntitiesContext : DbContext
{ }
种子数据继承DropCreateDatabaseIfModelChanges.
public class EntitiesInitializer : DropCreateDatabaseIfModelChanges<EntitiesContext>
{
}
配置项目连接字符串。
<connectionStrings>
<add name="EntitiesContext" providerName="System.Data.SqlClient" connectionString="Server=(localdb)\v11.0; Database=CompanyDB; Trusted_Connection=true; MultipleActiveResultSets=true" />
</connectionStrings>
在项目全局文件中启用种子数据的配置。
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register); // Init the database
Database.SetInitializer(new EntitiesInitializer());
}
在NuGet中输入odata,安装V4.0版本。
关于ODataController的增删改查,在"ASP.NET Web API基于OData的增删改查,以及处理实体间关系"比较详细的描述,这里略去,把重点放在前端的调用上。
先来看界面:
这里有个主视图,如下:
<html ng-app="mainApp">
<head>
<link href="Content/styles/toastr.css" rel="stylesheet" />
<link href="Content/styles/loading-bar.css" rel="stylesheet" /> <script src="Content/scripts/jquery-2.1.1.js"></script>
<script src="Content/scripts/bootstrap.js"></script>
<script src="Content/scripts/angular.js"></script>
<script src="Content/scripts/angular-resource.js"></script>
<script src="Content/scripts/toastr.js"></script>
<script src="Content/scripts/loading-bar.js"></script>
<script src="Content/scripts/main.js"></script>
<script src="app/services.js"></script>
<script src="app/controllers.js"></script>
</head>
<body ng-controller="appCtrl" ng-init="getTop10Employees()">
<tbody ng-repeat="emp in employees">
<tr ng-click="setEmployee(emp)">
<td>{{emp.ID}}</td>
<td>{{emp.FirstName}}</td>
<td>{{emp.Surname}}</td>
<td>{{emp.Email}}</td>
</tr>
</tbody> <!--更新或删除-->
<form>
<input type="text" id="id" ng-model="currentEmployee.ID" disabled>
<input type="text" id="firstName" ng-model="currentEmployee.FirstName">
<input type="text"id="surname" ng-model="currentEmployee.Surname">
<input type="email" id="inputEmail" ng-model="currentEmployee.Email">
<input type="text" id="city" ng-model="currentEmployee.City" disabled>
<input type="text" id="country" ng-model="currentEmployee.Country" disabled>
<input type="text" id="state" ng-model="currentEmployee.State" disabled>
<input type="text" id="company" ng-model="currentEmployee.Company" disabled>
<button type="button" ng-click="updateEmployee()">Update</button>
<button type="button" ng-click="deleteEmployee()">Delete</button>
</form> <!--添加-->
<form role="form">
<input type="text" name="firstname" ng-model="newEmployee.FirstName" />
<input type="text" name="surname" ng-model="newEmployee.Surname" />
<input type="text" name="email" ng-model="newEmployee.Email" />
<button type="button" ng-click="addEmployee()">Add</button>
</form>
<script type="text/javascript">
$(function () {
toastr.options = {
"positionClass": "toast-bottom-right",
"preventDuplicates": true,
"progressBar": true,
"timeOut": "3000",
}
});
</script>
</body>
</html>
一般来说,前端针对某个领域的操作有多个,chsakell的一种写法特别值得推荐,那就是把针对某个领域的操作,在AngularJS中,用$resource封装到一个服务中去。如下:
angular.module('mainApp')
.factory('employeeService', function ($resource) {
var odataUrl = '/odata/Employees';
return $resource('', {},
{
'getAll': { method: 'GET', url: odataUrl },
'getTop10': { method: 'GET', url: odataUrl + '?$top=10' },
'create': { method: 'POST', url: odataUrl },
'patch': { method: 'PATCH', params: { key: '@key' }, url: odataUrl + '(:key)' },
'getEmployee': { method: 'GET', params: { key: '@key' }, url: odataUrl + '(:key)' },
'getEmployeeAdderss': { method: 'GET', params: { key: '@key' }, url: odataUrl + '(:key)' + '/Address' },
'getEmployeeCompany': { method: 'GET', params: { key: '@key' }, url: odataUrl + '(:key)' + '/Company' },
'deleteEmployee': { method: 'DELETE', params: { key: '@key' }, url: odataUrl + '(:key)' },
'addEmployee': { method: 'POST', url: odataUrl }
});
}).factory('notificationFactory', function () {
return {
success: function (text) {
toastr.success(text, "Success");
},
error: function (text) {
toastr.error(text, "Error");
}
};
})
然后针对Employee,在mainApp中增减一个controller用来针对Employee的各种操作。
angular.module('mainApp')
.controller('appCtrl', function ($scope, employeeService, notificationFactory) { //存储当前用户
$scope.currentEmployee = {}; // Get Top 10 Employees
$scope.getTop10Employees = function () {
(new employeeService()).$getTop10()
.then(function (data) { //存储所有用户
$scope.employees = data.value;
$scope.currentEmployee = $scope.employees[0]; //相当于设置Empoyee的导航属性
$scope.setCurrentEmployeeAddress();
$scope.setCurrentEmployeeCompany(); //通知
notificationFactory.success('Employeess loaded.');
});
}; // Set active employee for patch update
$scope.setEmployee = function (employee) {
$scope.currentEmployee = employee;
$scope.setCurrentEmployeeAddress();
$scope.setCurrentEmployeeCompany();
}; //设置当前Employee的地址
$scope.setCurrentEmployeeAddress = function () {
//获取当前Employee
var currentEmployee = $scope.currentEmployee; return (new employeeService({
"ID": currentEmployee.ID,
})).$getEmployeeAdderss({ key: currentEmployee.ID })
.then(function (data) {
$scope.currentEmployee.City = data.City;
$scope.currentEmployee.Country = data.Country;
$scope.currentEmployee.State = data.State;
});
} //设置当前Employee的Company
$scope.setCurrentEmployeeCompany = function () {
var currentEmployee = $scope.currentEmployee; return (new employeeService({
"ID": currentEmployee.ID,
})).$getEmployeeCompany({ key: currentEmployee.ID })
.then(function (data) {
$scope.currentEmployee.Company = data.Name;
});
} // Update Selected Employee
$scope.updateEmployee = function () {
var currentEmployee = $scope.currentEmployee;
console.log(currentEmployee.Email);
if (currentEmployee) {
return (new employeeService({
"ID": currentEmployee.ID,
"FirstName": currentEmployee.FirstName,
"Surname": currentEmployee.Surname,
"Email": currentEmployee.Email
})).$patch({ key: currentEmployee.ID })
.then(function (data) {
notificationFactory.success('Employee with ID ' + currentEmployee.ID + ' updated.')
});
}
} $scope.deleteEmployee = function () {
var currentEmployee = $scope.currentEmployee; return (new employeeService({
"ID": currentEmployee.ID,
})).$deleteEmployee({ key: currentEmployee.ID })
.then(function (data) {
notificationFactory.success('Employee with ID ' + currentEmployee.ID + ' removed.');
$scope.getTop10Employees();
});
} $scope.addEmployee = function () {
var newEmployee = $scope.newEmployee; return (new employeeService({
"FirstName": newEmployee.FirstName,
"Surname": newEmployee.Surname,
"Email": newEmployee.Email,
"AddressID": 1, // normally obtained from UI
"CompanyID": 3 // normally obtained from UI
})).$addEmployee()
.then(function (data) {
notificationFactory.success('Employee ' + newEmployee.FirstName + ' ' + newEmployee.Surname
+ ' added successfully'); $scope.newEmployee = {};
});
}
});
对一个前端AngularJS,后端OData,ASP.NET Web API案例的理解的更多相关文章
- 对一个前端使用AngularJS后端使用ASP.NET Web API项目的理解(4)
chsakell分享了一个前端使用AngularJS,后端使用ASP.NET Web API的项目. 源码: https://github.com/chsakell/spa-webapi-angula ...
- 对一个前端使用AngularJS后端使用ASP.NET Web API项目的理解(3)
chsakell分享了一个前端使用AngularJS,后端使用ASP.NET Web API的项目. 源码: https://github.com/chsakell/spa-webapi-angula ...
- 对一个前端使用AngularJS后端使用ASP.NET Web API项目的理解(2)
chsakell分享了一个前端使用AngularJS,后端使用ASP.NET Web API的项目. 源码: https://github.com/chsakell/spa-webapi-angula ...
- 对一个前端使用AngularJS后端使用ASP.NET Web API项目的理解(1)
chsakell分享了一个前端使用AngularJS,后端使用ASP.NET Web API的项目. 源码: https://github.com/chsakell/spa-webapi-angula ...
- 购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(3)--Idetity,OWIN前后端验证
原文:购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(3)--Idetity,OWIN前后端验证 chsakell分享了前端使用AngularJS,后端使用ASP. ...
- 购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(2)--前端,以及前后端Session
原文:购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(2)--前端,以及前后端Session chsakell分享了前端使用AngularJS,后端使用ASP.NE ...
- 购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(1)--后端
原文:购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(1)--后端 chsakell分享了前端使用AngularJS,后端使用ASP.NET Web API的购物车 ...
- 前端使用AngularJS的$resource,后端ASP.NET Web API,实现增删改查
AngularJS中的$resource服务相比$http服务更适合与RESTful服务进行交互.本篇后端使用ASP.NET Web API, 前端使用$resource,实现增删改查. 本系列包括: ...
- 通过Knockout.js + ASP.NET Web API构建一个简单的CRUD应用
REFERENCE FROM : http://www.cnblogs.com/artech/archive/2012/07/04/Knockout-web-api.html 较之面向最终消费者的网站 ...
随机推荐
- Regular Expression Matching & Wildcard Matching
Regular Expression Matching Implement regular expression matching with support for '.' and '*'. '.' ...
- 003_vim使用tip
vim 使用tip 编写python程序 自动插入头信息: #!/usr/bin/env python # coding=utf-8 输入.或按TAB键会触发代码补全功能 :w保存代码之后会自动检查代 ...
- js如何判断一个对象是不是Array?
在开发中,我们经常需要判断某个对象是否为数组类型,在Js中检测对象类型的常见方法都有哪些呢? typeof 操作符 对于Function, String, Number ,Undefined 等几种类 ...
- nginx安装报错:configure: error: the HTTP rewrite module requires the PCRE library
参考:http://blog.51cto.com/williamx/958398 需要安装pcre-devel与openssl-devel yum -y install pcre-devel open ...
- hashlib和hmac
hashlib hashlib模块用于加密相关的操作,代替了md5和sha模块,主要提供SHA1,SHA224,SHA256,SHA384,SHA512,MD5算法. #!/usr/bin/env p ...
- Django项目之cookie+session
原文:https://www.cnblogs.com/sss4/p/7071334.html HTTP协议 是短连接.且状态的,所以在客户端向服务端发起请求后,服务端在响应头 加入cokie响应给浏览 ...
- CEF 中的那些坑
CEF (Chromium Embedded Framework) 的大名也听说很久了,最近因为客户的需求,简单地研究了一下.结果遇到了一个接一个的坑,且慢慢道来.比之前用QtWebkit的坑还要多和 ...
- spark sql中保存数据的几种方式
从官网来copy过来的几种模式描述: Scala/Java Python Meaning SaveMode.ErrorIfExists(default) "error"(defau ...
- Stable Match
稳定婚姻问题 主要就是处理两个数组 boy[i][j] 存放第i个男的第j喜欢的女的 存的是女的编号!! girl[i][j] 存放 第i个女的对第j个男的的好感度 存的是值 然后只要 ...
- 初识MYSQL2
mysql的配置 MySql默认的端口号是3306 默认字符集的设置 在mysql的安装目录,会看到my.ini文件! my.ini文件介绍 01.default-character-set=utf8 ...