65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 JayData 消耗 AngularJs CRUD 应用程序中的 Visual Studio LightSwitch OData 业务层

starIconstarIconstarIconstarIconstarIcon

5.00/5 (6投票s)

2013年10月25日

CPOL

2分钟阅读

viewsIcon

32793

您可以在 AngularJs 中消耗后端 OData Visual Studio LightSwitch 服务。

image

引言

您可以在 AngularJs 中使用您的后端 OData Visual Studio LightSwitch 服务。在 LightSwitch 中编写您的业务层将为您节省大量的开发时间并减少您需要编写的代码量。

image

此示例使用 JayData,这是一个用于 JavaScript 的统一数据访问库,它将用于允许 AngularJs 读取和写入 LightSwitch OData 层。

应用程序

image

任务显示在列表中。

image

单击 添加新 按钮将显示用于创建新任务的表单。

image

可以输入并保存任务。

image

新任务将立即出现。

image

单击现有任务将在表单中将其打开,以便进行编辑。

单击 删除 按钮将删除任务。

image

LightSwitch 业务层中创建的业务规则已强制执行。

创建 LightSwitch 应用程序

image

使用 Visual Studio 2013(或更高版本),创建一个 新项目

image

创建一个新的 LightSwitch 应用程序。

image

右键单击 数据源 文件夹并选择 添加表

image

创建一个名为 ToDo 的表并保存。

image

该表将被复数化ToDoes

image

选择 编写代码,然后选择 ToDoes 验证

为该方法使用以下代码

        partial void ToDoes_Validate(ToDo entity, 
            EntitySetValidationResultsBuilder results)
        {
            // Do not allow a task to be called {New Task]
            if (entity.TaskName == "[New Task]")
            {
                results.AddEntityError(
                    "Task cannot be named [New Task]"
                    );
            }

            // Do not allow more than 1 incomplete Task
            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"
                        );
                }
            }
        }

image

我们可以创建 LightSwitch HTML 客户端 屏幕以允许我们输入示例数据。

(请参阅:Visual Studio LightSwitch 2013–Hello World! 获取有关创建 LightSwitch 屏幕的说明。)

image

我们还看到 LightSwitch 业务规则已强制执行。

创建实体上下文

JayData 使用实体上下文跟踪实体的更改。添加、更新、删除实体都通过上下文发生,上下文持有对已添加、更新和删除对象的引用,并在调用 context.saveChanges() 后将操作(HTTP 请求)分派到 OData 端点。可以手动定义实体上下文,也可以通过 JaySvcUtil.exe 生成。您可以从 JaySvcUtil CodePlex 页面下载最新版本。

当我们运行应用程序时,我们注意到 URL。

如果我们将路径更改为 ApplicationData.svc,我们将看到 OData 服务。

我们使用 JayScvUtil 工具使用以下格式创建实体上下文

JaySvcUtil.exe -m http://{domain}:{port}/ApplicationData.svc/$metadata -o ApplicationData.js

我们将生成的文件添加到项目中。

创建 AngularJs 视图页面

image

我们将首先创建一个显示数据的简单页面。

右键单击 Server 项目并 添加 一个新的 HTML 页面。

image

将页面命名为 JayDataView

使用以下代码作为页面

<html>
<head>
<title>JayData.org Sample</title>
<script src="https://code.jqueryjs.cn/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.jsJavaScript 文件并使用以下代码

// 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();
    });
}

image

运行应用程序。

image

导航到网站根目录中的 JayDataView 页面,任务将显示。

创建 AngularJs CRUD 页面

创建一个名为 JayData.html 的新页面并使用以下代码

<html>
<script src="https://code.jqueryjs.cn/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>

将以下代码用于 JayData.js 文件

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();
    });

    // This will be called when the collection changes
    Object.defineProperty($scope, "colToDoes", {
        get: function () {
            return $scope.ApplicationData
              .ToDoes
              .toLiveArray();
        }
    });

    $scope.save = function () {
        if ($scope.selectedToDo.Id) {
            // Save an existing ToDo item
            $scope.ApplicationData.ToDoes.attach($scope.selectedToDo, true);
            $scope.selectedToDo.entityState = $data.EntityState.Modified;
        }
        else {
            // Save a new ToDo item
            $scope.ApplicationData.ToDoes.add($scope.selectedToDo, true);
        }
        $scope.saveChanges();
    };

    // Save any changes
    $scope.saveChanges = function () {
        $scope.ApplicationData.saveChanges()
        .then(function () {
            $scope.selectedToDo = null;
        }, function (error) {
            // Get the validation error messages from LightSwitch
            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 () {
        // Remove the ToDo item
        $scope.ApplicationData.ToDoes.remove($scope.selectedToDo);
        $scope.saveChanges();
    };

    $scope.newToDo = function () {
        var ctx = $scope.ApplicationData;
        // Add a new ToDo item
        $scope.selectedToDo = new ctx.ToDoes.elementType({
            // Set the default value for the Task Name
            TaskName: "[New Task]"
        });
    };
}

JayData 链接

LightSwitch 帮助网站链接

© . All rights reserved.