在本文中,将探讨如何使用AngularJS和LightSwitch创建一个CRUD(创建、读取、更新、删除)应用程序。将通过JayData与OData服务进行交互,以实现数据的增删改查功能。
首先,需要创建一个LightSwitch应用程序。LightSwitch是一个快速应用程序开发平台,它允许开发者快速构建业务应用程序。将使用Visual Studio 2013或更高版本来创建这个应用。
在Visual Studio中,创建一个新的LightSwitch项目。然后,右键单击“数据源”文件夹,选择“添加表”。创建一个名为“ToDo”的表,并保存。这个表将被复数化为“ToDoes”。
接下来,需要编写一些业务规则。在“编写代码”视图中,选择“ToDoes Validate”。将使用以下JavaScript代码来定义业务规则:
partial void ToDoes_Validate(ToDo entity, EntitySetValidationResultsBuilder results) {
// 不允许任务命名为"[New Task]"
if (entity.TaskName == "[New Task]") {
results.AddEntityError("Task cannot be named [New Task]");
}
// 不允许有超过1个未完成任务
if (entity.IsComplete == false) {
int intCountOfIncomplete = this.DataWorkspace.ApplicationData.ToDoes.Where(x => x.IsComplete == false).Count();
if (intCountOfIncomplete > 0) {
results.AddEntityError("Cannot have more than 1 incomplete Task");
}
}
}
这些规则将确保任务名称不是默认的"[New Task]",并且不能有超过一个未完成的任务。
JayData使用实体上下文来跟踪实体的变化。添加、更新、删除实体都通过上下文进行,上下文持有对添加、更新和删除对象的引用,并在调用context.saveChanges()后将操作(HTTP请求)分派到OData端点。
可以使用JaySvcUtil.exe工具来创建实体上下文。首先,运行应用程序并记录URL。然后,将路径更改为ApplicationData.svc,就可以看到OData服务。
使用以下格式使用JaySvcUtil工具创建实体上下文:
JaySvcUtil.exe -m http://{domain}:{port}/ApplicationData.svc/$metadata -o ApplicationData.js
将生成的文件添加到项目中。
接下来,将创建一个简单的页面来显示数据。在服务器项目中右键单击并添加一个新的HTML页面。将页面命名为JayDataView。将使用以下代码:
<html>
<head>
<title>JayData.org Sample</title>
<script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="http://code.angularjs.org/1.2.0-rc.3/angular.js"></script>
<script src="http://include.jaydata.org/datajs-1.0.3.js"></script>
<script src="http://include.jaydata.org/jaydata.js"></script>
<script src="http://include.jaydata.org/jaydatamodules/angular.js"></script>
<script src="JayDataView.js"></script>
<script src="ApplicationData.js"></script>
</head>
<body data-ng-app="app">
<div ng-controller="ToDoesController">
<ul>
<li ng-repeat="ToDo in ToDoes">
<input id="checkSlave" type="checkbox" ng-model="ToDo.IsComplete">
{{ToDo.TaskName}}
</li>
</ul>
</div>
</body>
</html>
然后,创建一个名为JayDataView.js的JavaScript文件,并使用以下代码:
// Create an Angular app and inject JayData
var app = angular.module('app', ['jaydata']);
// Define a controller
function ToDoesController($scope, $data) {
// Make a empty collection for ToDoes
$scope.ToDoes = [];
var ApplicationData = new LightSwitchApplication.ApplicationData({
name: 'oData',
oDataServiceHost: '/ApplicationData.svc'
});
ApplicationData.onReady(function() {
// Connect the ToDoes collection to the
// JayData toLiveArray()
$scope.ToDoes = ApplicationData.ToDoes.toLiveArray();
});
}
运行应用程序。导航到网站根目录下的JayDataView页面,任务将显示出来。
现在,将创建一个新的页面,名为JayData.html,并使用以下代码:
<html>
<script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="http://code.angularjs.org/1.2.0-rc.3/angular.js"></script>
<script src="http://include.jaydata.org/datajs-1.0.3.js"></script>
<script src="http://include.jaydata.org/jaydata.js"></script>
<script src="http://include.jaydata.org/jaydatamodules/angular.js"></script>
<script src="JayData.js"></script>
<script src="ApplicationData.js"></script>
<body>
<div data-ng-app="app" ng-controller="ToDoEditorController">
<ul>
<li ng-repeat="ToDo in colToDoes">
<input id="checkbox" type="checkbox" ng-model="ToDo.IsComplete" disabled="disabled">
<a href="#" ng-click="$parent.selectedToDo = ToDo">
{{ToDo.TaskName}}
</a>
</li>
</ul>
<button ng-click="newToDo()">
add new
</button>
<p>
<form ng-if="selectedToDo">
<fieldset style="width: 300px; background-color: #FFFFCC;">
<legend>{{selectedToDo.TaskName}}</legend>
<br/>
<label>
<span>
<strong>Id:</strong>
</span>
<span>
{{selectedToDo.Id}}
</span>
<span>
<br/>
<strong>Task Name:</strong>
</span>
<input ng-model="selectedToDo.TaskName" size="20"/>
<span>
<br/>
<strong>Is Complete:</strong>
</span>
<input type="checkbox" ng-model="selectedToDo.IsComplete"/>
<br/>
<br/>
</label>
<button ng-click="save()">
Save
</button>
<button ng-click="remove()">
Remove
</button>
</fieldset>
</form>
</p>
</div>
</body>
</html>
var app = angular.module('app', ['jaydata']);
function ToDoEditorController($scope, $data) {
$scope.ToDoes = [];
$scope.selectedToDo = null;
var ApplicationData = new LightSwitchApplication.ApplicationData({
name: 'oData',
oDataServiceHost: '/ApplicationData.svc'
});
ApplicationData.onReady(function() {
$scope.ApplicationData = ApplicationData;
$scope.ToDoes = ApplicationData.ToDoes.toLiveArray();
});
Object.defineProperty($scope, "colToDoes", {
get: function() {
return $scope.ApplicationData.ToDoes.toLiveArray();
}
});
$scope.save = function() {
if ($scope.selectedToDo.Id) {
$scope.ApplicationData.ToDoes.attach($scope.selectedToDo, true);
$scope.selectedToDo.entityState = $data.EntityState.Modified;
} else {
$scope.ApplicationData.ToDoes.add($scope.selectedToDo, true);
}
$scope.saveChanges();
};
$scope.saveChanges = function() {
$scope.ApplicationData.saveChanges()
.then(function() {
$scope.selectedToDo = null;
}, function(error) {
var xml = error.message,
xmlDoc = $.parseXML(xml),
$xml = $(xmlDoc),
$ValidationResults = $xml.find("ValidationResults");
angular.forEach($ValidationResults, function(ValidationResult) {
angular.forEach(ValidationResult.childNodes, function(childNode) {
alert(childNode.childNodes[0].textContent);
});
});
$scope.ApplicationData.stateManager.reset();
});
};
$scope.remove = function() {
$scope.ApplicationData.ToDoes.remove($scope.selectedToDo);
$scope.saveChanges();
};
$scope.newToDo = function() {
var ctx = $scope.ApplicationData;
$scope.selectedToDo = new ctx.ToDoes.elementType({
TaskName: "[New Task]"
});
};
}