【发布时间】:2014-09-23 18:49:50
【问题描述】:
我在让 SELECT 与 Angular、ASP.NET Web API v2 和 Entity Framework Code First 一起工作时遇到问题。我有两个简单的对象,Products 和 Categories,用以下模型定义:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string SerialNumber { get; set; }
public string Notes { get; set; }
public Category Category { get; set; }
public ApplicationUser User { get; set; }
}
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public ApplicationUser User { get; set; }
}
然后我有以下 Angular 标记:
<div class="form-group">
<label for="inputSerial" class="col-lg-3 control-label">Category</label>
<div class="col-lg-9">
<select class="form-control" id="selectCategory" ng-model="product.Category" ng-options="category as category.Name for category in categories"></select>
</div>
</div>
最后,以下 Angular app.js 脚本:
app.controller('SerialController', function ($scope, $http, $routeParams, $cookies) {
$http({
method: 'GET',
url: 'http://localhost:20697/api/categories/' + '?access_token=' + $cookies.token,
headers: { 'Authorization': 'Bearer ' + $cookies.token }
}).success(function (data, status, headers) {
$scope.categories = data;
}).error(function (data, status, headers) {
$scope.error = reason;
});
var onGetComplete = function (response) {
$scope.product = response.data;
};
var onError = function (reason) {
$scope.error = reason;
};
if ($routeParams.id > 0) {
$http.get("http://localhost:20697/api/products/" + $routeParams.id)
.then(onGetComplete, onError);
}
$scope.saveProduct = function () {
if ($scope.product.Id > 0) {
$http({
method: 'PUT',
data: $scope.product,
url: 'http://localhost:20697/api/products/' + $scope.product.Id
}).success(function (data, status, headers) {
}).error(function (data, status, headers) {
});
}
else {
$http({
method: 'POST',
data: $scope.product,
url: 'http://localhost:20697/api/products/'
}).success(function (data, status, headers) {
}).error(function (data, status, headers) {
});
}
};
});
有了这个,我得到了正确填充数据库中的类别的 SELECT。但是,我有两个问题。
问题 #1)如果在数据库中设置了类别,它会从 web api 发送到 Angular,但实际上并没有在 select 中选择正确的条目。
问题 #2)当我在下拉列表中选择一个条目并保存时,angular 会将产品对象发送回具有正确类别集的 api。我什至可以在 api 控制器中看到它。但是,它实际上并没有将类别选择保存到数据库中的产品中。这是我的产品更新控制器代码:
// PUT: api/Products/5
[ResponseType(typeof(void))]
public IHttpActionResult PutProduct(int id, Product product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != product.Id)
{
return BadRequest();
}
db.Entry(product).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!ProductExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return StatusCode(HttpStatusCode.NoContent);
}
在实际的数据库中,Entity Framework Code 首先将 products 表中的类别添加为 Category_Id,这是我所预料的。
对此的任何帮助将不胜感激。谢谢!
更新:在以下建议不太正确后,我在网上进行了更多搜索。我从 Scott Allen 那里找到了这篇文章。 http://odetocode.com/blogs/scott/archive/2013/06/19/using-ngoptions-in-angularjs.aspx。从那以后,我可以使用我的原始代码,然后在角度控制器中添加一些代码来进行初始选择。我还必须更改控制器中事物的顺序(一旦我开始工作,我需要进一步重构它)。这是控制器的更新部分:
$http({
method: 'GET',
url: 'http://localhost:20697/api/categories/' + '?access_token=' + $cookies.token,
headers: { 'Authorization': 'Bearer ' + $cookies.token }
}).success(function (data, status, headers) {
$scope.categories = data;
if ($routeParams.id > 0) {
$http.get("http://localhost:20697/api/products/" + $routeParams.id)
.then(onGetComplete, onError);
}
}).error(function (data, status, headers) {
$scope.error = reason;
});
var onGetComplete = function (response) {
$scope.product = response.data;
for (var i = 0; i < $scope.categories.length; i++) {
if ($scope.categories[i].Id == $scope.product.Category.Id) {
$scope.product.Category = $scope.categories[i];
break;
}
}
};
有了这个,我现在可以让初始选择正常工作,并且正确的类别选择被发送回 API。 问题是,无论出于何种原因,Entity Framework 在更新产品时都会跳过类别选择。这是正在执行的 T-SQL:
DECLARE @2 AS SQL_VARIANT;
DECLARE @0 AS SQL_VARIANT;
DECLARE @1 AS SQL_VARIANT;
SET @2 = NULL;
SET @0 = NULL;
SET @1 = NULL;
UPDATE [dbo].[Products]
SET [Name] = @0, [SerialNumber] = @1, [Notes] = NULL
WHERE ([Id] = @2)
如您所见,Category_Id 根本没有更新。我需要做些什么来告诉 EF 它应该更新类别的外键以及产品信息吗?
谢谢
【问题讨论】:
标签: asp.net angularjs select data-binding asp.net-web-api