我有一个HTML部分,我也试图绑定AJAX数据。出于某种原因,似乎我必须将AJAX服务调用放在指令的link函数中。我不能把它放在控制器中;我在这样的指令中这样做:
link: function(scope){
MyService.getData().then(function(res){
scope.myData = res.data;
}, function(res){
throw new Error('Error getting data');
});
}
首先,我很好奇为什么我不能在我的控制器中执行此操作。但是,一旦我得到它,我想对数据进行一些操作。是否所有这些都需要在链接函数中发生。在控制器中循环$scope.myData
将无法正常工作,因为它尚未定义?我可以以某种方式在我的控制器中使用我的AJAX数据,而无需在链接文件中执行我的逻辑吗?
答案 0 :(得分:7)
任务可以通过各种方式完成,但问题是哪种做法最好。 首先,如果你有一个部分指令,你想绑定它,你可以在指令的控制器中做到这一点
app.directive('myPartial', function() {
return {
restrict:'AE',
template:'<pre>[{{myData| json}}]</pre>',
scope:true,
link:function(scope, elem, attrs) {
/*avoid using model manipulation in link function as it is mostly used
for DOM manipulation such as angular.element(elem).addClass('myTemplateClass');*/
},
controller: function($scope,MyService){
MyService.getData().then(function(dataFromServer){
scope.myData = dataFromServer;
}, function(err){
throw new Error('Error getting data : ' + err);
});
}
};
});
使用AngularJS时,您必须拥有 THIN 控制器和 THICK 服务..如果您需要操纵数据。在服务中执行此操作并将此类形式的数据返回到可直接分配给控制器的控制器。这是最好的做法。即在你的服务中。这样做
app.factory('MyService',function($http,$q){
var _modifyGetData = function(serverData){
// modify your data here...
// for example -> serverData.usersCount = serverData.users.length;
return serverData;
};
var getData = function(){
var dfd = $q.defer();
$http.get(/*Some url here*/).then(function(res){
var data = res.data;
// manipulate all your data using a function maybe
data = _modifyGetData(data);
dfd.resolve(data); //resolve the modified data
});
return dfd.promise;
}
return {
getData:getData
};
});
希望这有帮助。
可能有所帮助的一些在线资源: https://scotch.io/tutorials/making-skinny-angularjs-controllers https://teamgaslight.com/blog/4-lessons-learned-doing-angular-on-rails
答案 1 :(得分:0)
您是如何将它放入控制器的?我的控制器中有一个函数,我通过ng-init调用,以加载我的数据。基于您的代码段的示例:
.controller('myCtrl', function ($scope, MyService) {
$scope.initData = function(){
MyService.getData().then(function(res){
$scope.myData = res.data;
}, function(res){
throw new Error('Error getting data');
});
}
}
然后在我的部分中,在我的一个HTML标签中:
<div ng-init="initData()"></div>
只需将ng-init添加到您的一个HTML标记即可发送呼叫。不确定它是否正确,但它适用于我的场景,也适用于你的场景。
答案 2 :(得分:0)
显然有几种方法可以实现这一目标;根据您的需要,有些可能比其他人更好。我建议您更多地考虑从服务中获取的数据及其所属的数据。
无论哪种方式,您都应该使用上面的(3)来提供服务。在处理本地缓存时要注意陷阱。 希望这会有所帮助。
编辑: 如果您正在寻找编码示例,请告诉我 - 您的问题似乎更多关于&#34;我的选择是什么&#34;而不是具体的技术实施细节。
干杯!
答案 3 :(得分:0)
您可以从控制器中调用该服务。
你不能的原因是什么?
YourController.$inject = ['MyService', '$scope'];
function YourController(myService, $scope) {
myService.getData().then(
function(res) {
$scope.myData = res.data;
// or manipulate the data
$scope.apply();
})
}
答案 4 :(得分:0)
您可以在指令的控制器中执行此操作,例如:
app.directive('output', function() {
return {
retrict:'E',
replace:true,
template:'<pre>[{{MyData | json}}]</pre>',
scope:true,
controller:function(MyService, $scope) {
$scope.MyData = $scope.MyData || {};
MyService.getData().then(function(value){
$scope.MyData.value = value;
});
},
link:function(scope, element, attrs) {
scope.MyData = scope.MyData || {};
}
};
});
看到这个小提琴:http://jsfiddle.net/oq2m149e