我一直在使用AngularJs在ASP.NET webforms中进行数据绑定。
我有以下角度:
(function () {
var app = angular.module("registrationModule", []);
app.factory("exampleService", exampleService);
function exampleService($http) {
function getData(id) {
return $http.post("LegacyPage.aspx/GetData", { id: id })
.then(function (response) {
return response.data; //data comes back as json
//Also tried response.data.d
});
};
return {
getData: getData
};
};
app.controller("MainCtrl", ["$scope", "exampleService", MainCtrl]);
function MainCtrl($scope, exampleService) {
$scope.generateText = "Generate";
$scope.loading = false;
function onComplete(data) {
Unload(data);
}
function err(reason) {
Unload("Ajax has failed.");
}
$scope.GetData = function (id) {
Load();
exampleService.getData(id).then(onComplete, err);
}
function Unload(result) {
$scope.loading = false;
$scope.generating = false;
$scope.generateText = "Generate";
$scope.theData = result; //does not work
//I have tried (with no success):
//$scope.$apply(function () {
//$scope.theData = result;
//});
//$scope.theData = JSON.parse(result);
//$scope.theData = angular.fromJson(result);
}
function Load() {
$scope.loading = true;
$scope.generating = true;
$scope.generateText = "Generating...";
}
};
}());
我的HTML:
<div ng-app="registrationModule">
<div ng-controller="MainCtrl">
<input style="display: block; margin: 0 auto;" type="text" class="form-control" placeholder="ID" ng-model="id" />
<input ng-click="GetData(id)" type="button" class="btn btn-primary btn-lg" value="{{generateText}}" ng-disabled="generating" />
<div class="row">
<div class="span10">
<table class="table table-responsive table-hover table-condensed">
<tr>
<th>ID</th>
<th>Activity Code</th>
<th>Duration</th>
<th>Date Created</th>
</tr>
<tr ng-repeat="element in theData">
<td>{{element.ID}}</td>
<td>{{element.ActivityCode}}</td>
<td>{{element.Duration}}</td>
<td>{{element.DateCreated}}</td>
</tr>
</table>
<br />
</div>
</div>
</div>
</div>
代码隐藏/后端c#:
[WebMethod]
public static string GetData(int id)
{
var dt = GetData(id);
if (dt == null) return "";
var json = dt.Serialize() ?? "";
return json;
}
public static string Serialize(this DataTable dt)
{
if (dt == null)
{
throw new NullReferenceException("dt parameter cannot be null");
}
try
{
var serializer = new JavaScriptSerializer();
var rows = new List<Dictionary<string, object>>();
Dictionary<string, object> row;
foreach (DataRow dr in dt.Rows)
{
row = new Dictionary<string, object>();
foreach (DataColumn col in dt.Columns)
{
row.Add(col.ColumnName, dr[col]);
}
rows.Add(row);
}
return serializer.Serialize(rows);
}
catch
{
return null;
}
}
基本上,数据以JSON形式返回,但未成功绑定。我正在以角度恢复JSON,但我无法处理它。我想我只是遗漏了一些非常简单的东西,但尚未找到解决方案
答案 0 :(得分:1)
我想我可能已经找到了你的问题。在你的getData()函数中,你将id参数命名为“studentId”,但稍后将其称为“id”。这是修复:
function getData(studentId) {
return $http.post("LegacyPage.aspx/GetData", {
id: studentId // This used to be "id", but needed to be "studentId"
})
.then(function (response) {
return response.data;
});
};
修改强>
听起来您的问题可能是您的API返回单个哈希对象,如下所示:
$scope.theData = {
ID: 1,
ActivityCode: 'foo'
...etc
}
如果是这种情况,则不需要使用ng-repeat指令来显示一个对象。你只需改变你的观点:
<div ng-app="registrationModule">
<div ng-controller="MainCtrl">
<input style="display: block; margin: 0 auto;" type="text" class="form-control" placeholder="ID" ng-model="id" />
<input ng-click="GetData(id)" type="button" class="btn btn-primary btn-lg" value="{{generateText}}" ng-disabled="generating" />
<div class="row">
<div class="span10">
<table class="table table-responsive table-hover table-condensed">
<tr>
<th>ID</th>
<th>Activity Code</th>
<th>Duration</th>
<th>Date Created</th>
</tr>
<tr>
<td>{{theData.ID}}</td>
<td>{{theData.ActivityCode}}</td>
<td>{{theData.Duration}}</td>
<td>{{theData.DateCreated}}</td>
</tr>
</table>
<br />
</div>
</div>
</div>
</div>
如果您的API返回一个对象数组以进行迭代,您只需要使用ng-repeat指令:
$scope.theData = [{
ID: 1,
ActivityCode: 'foo'
...etc
}, {
ID: 2,
ActivityCode: 'bar'
...etc
}]
答案 1 :(得分:0)
您没有将response.data
绑定到任何变量。您需要在控制器中添加$scope.theData = response.data;
。
[编辑:] 更正,您的代码感到困惑。从以下位置更改控制器:
$scope.theData = result;
至$scope.theData = result.data;
至于您的服务,请删除.then(...)
因为它没有做任何事情。
function getData(studentId) {
return $http.post("LegacyPage.aspx/GetData", { id: id });
};
除非您打算更改回复,否则您需要添加return
:
function getData(studentId) {
return $http.post("LegacyPage.aspx/GetData", { id: id })
.then(function (response) {
return response.data;
});
};
至于标准,我建议使用.catch(err)
,因为这样你就可以链接几个.then(...)
语句并仍然使用一个错误处理程序。它也更容易阅读。
exampleService.getData(id).then(onComplete).catch(err);
答案 2 :(得分:0)
所以想通了。问题是ng-repeat无法绑定数据。这是因为数据以字符串形式返回。所以每个对象的每个属性都是一个字符串,棱角分明显然不是那样的。我需要做的就是将后端代码更改为:
[WebMethod]
public static List<ReportData> GetData(int id)
{
var dt = GetData(id);
if (dt == null) return dt;
var reportElements = dt.ToObjectList<ReportData>();
//var json = dt.Serialize() ?? "";
return reportElements;
}
public class ReportData
{
public int Id { get; set; }
public string ActivityCode { get; set; }
public string Duration { get; set; }
public DateTime DateCreated { get; set; }
}
public static List<T> ToObjectList<T>(this DataTable table) where T : class, new()
{
try
{
var list = new List<T>();
foreach (var row in table.AsEnumerable())
{
T obj = new T();
foreach (var prop in obj.GetType().GetProperties())
{
try
{
PropertyInfo propertyInfo = obj.GetType().GetProperty(prop.Name);
propertyInfo.SetValue(obj, Convert.ChangeType(row[prop.Name], propertyInfo.PropertyType), null);
}
catch
{
continue;
}
}
list.Add(obj);
}
return list;
}
catch
{
return null;
}
}
所以现在它返回了我创建的类的通用列表。我使用扩展方法将我的数据表映射到类。在我的服务中,我现在使用:
function exampleService($http) {
function getData(id) {
return $http.post("LegacyPage.aspx/GetData", { id: id })
.then(function (response) {
return response.data; //data comes back as json
//Also tried response.data.d
});
};
return {
getData: getData
};
};
并在我的卸载功能中:
$scope.theData = result;