我正在尝试使用asp.net-mvc学习使用angular的正确方法。现在我正在做的是让asp.net引擎渲染我的视图,但我没有将任何信息作为模型传递给视图。我正在使用ng-init
来调用范围函数以将数据检索为json
。
例如我的索引视图的get动作方法如下:
public ActionResult Index()
{
return View();
}
我有另一个角度调用的控制器动作方法:
public ActionResult getMembersList()
{
List<CommunityMember> cmList = new List<CommunityMember>();
var members = db.Member.OrderBy(x => x.FirstName).ToList();
foreach (var m in members)
{
CommunityMember cm = new CommunityMember(m);
cmList.Add(cm);
}
return Json(cmList, JsonRequestBehavior.AllowGet);
}
(顺便说一句,我应该避免这个foreach循环吗?它只是创建一个我的CommunityMember视图模型的列表)
,角度函数如下所示:
$scope.getMembersList = function () {
$http.get("/Members/getMembersList")
.success(function (data) {
$scope.membersList = data;
}).error(function (data) {
console.log(data);
});
};
我的所有角度代码当前都在角度控制器中:
var myApp = angular.module("myApp", []);
myApp.controller('myIndexViewModel', function myIndexViewModel($scope, $http, $compile) {
//scope functions/variables
//http calls
//etc..
}
我觉得这不是最好的方法,想知道是否有更好的方法来做到这一点。我应该按照ng-init
的方式加载数据,然后使用注入的$http
来访问服务器吗?
我应该将所有$http
来电放在不同的地方吗?
感谢您的帮助!
答案 0 :(得分:0)
在foreach循环中你正在做的是将一个对象列表转换为另一个对象列表。这在函数式编程中被称为映射(投影),并且已经有一个linq方法来做。使用选择,它更简洁。
var members = db.Member.OrderBy(x => x.FirstName)
.Select(x=>new CommunityMember(){
Name=x.Some,
Age=x.Age
}).ToList();
控制器中的代码不太好。控制器的责任应该是数据并且不使用 $ http 来查看服务。将 $ http 调用移动到实现promise模式的自定义服务,以通知控制器。现在控制器没有任何逻辑,除了更新UI上的数据。
尽量避免使用Razor进行数据渲染,并将前视图从Razor中分离出来。 Js,html视图可以在任何地方托管。你也不必保留.Net项目。使你的服务器端表现为角度应用程序的Api层。所以让你的视图静态,让角度决定功能。
答案 1 :(得分:0)
确实从后端获取数据的ng-init isn't the best way。相反,您还有其他两个选择。
第一个是解决路线中的 getMembersList 。
第二个是解析控制器内的 getMembersList ,更新你的示波器然后隐藏你的装载机。
选项1(使用UI路由器):
state('members', {
url: '/members',
templateUrl: 'someTemplateURL',
controller: function(members) {
//Do something here
},
resolve: {
members: function($http) {
return $http.get("/Members/getMembersList")
}
}
})
选项2(使用controllerAs语法和ES6胖箭头的内部控制器):
memberModule.controller('membersCtrl', function ($http) {
this.loader = true;
$http.get("/Members/getMembersList")
.success((data) => {
this.membersList = data;
this.loader = false;
//Your view will pick up the change after the next digest cycle
})
}