Javascript 在哪里操作通过AJAX服务获取的数据?链接fn或控制器?
我有一个HTML部分,我也在尝试绑定AJAX数据。出于某种原因,似乎我必须将AJAX服务调用放在指令的link函数中。我不能把它放在控制器里;我在指令中这样做:Javascript 在哪里操作通过AJAX服务获取的数据?链接fn或控制器?,javascript,angularjs,ajax,model-view-controller,Javascript,Angularjs,Ajax,Model View Controller,我有一个HTML部分,我也在尝试绑定AJAX数据。出于某种原因,似乎我必须将AJAX服务调用放在指令的link函数中。我不能把它放在控制器里;我在指令中这样做: link: function(scope){ MyService.getData().then(function(res){ scope.myData = res.data; }, function(res){ throw new Error('Error getting data'); }); } 首先,
link: function(scope){
MyService.getData().then(function(res){
scope.myData = res.data;
}, function(res){
throw new Error('Error getting data');
});
}
首先,我很好奇为什么我不能在我的控制器中这样做。但是,一旦我得到数据,我还想对它进行一些操作。这一切都需要在链接函数中发生吗。在控制器中,通过
$scope.myData
循环将无法工作,因为它尚未定义?我可以在控制器中使用AJAX数据,而不必在链接文件中执行逻辑吗?如何将其放入控制器中?我的控制器中有一个函数,我通过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标记中即可发送调用。不确定这是否正确,但它适用于我的场景,也适用于你的场景。显然有几种方法可以实现这一点;根据您的需要,有些可能比其他更好。我建议您更多地考虑您从该服务中获得的数据及其所属位置
干杯 您可以从控制器调用该服务 你不能去的原因是什么
YourController.$inject = ['MyService', '$scope'];
function YourController(myService, $scope) {
myService.getData().then(
function(res) {
$scope.myData = res.data;
// or manipulate the data
$scope.apply();
})
}
您可以在指令的控制器中执行此操作,例如:
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 || {};
}
};
});
app.directive('output',function(){
返回{
检索:'E',
替换:正确,
模板:“[{MyData | json}}]”,
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);
});
}
};
});
范围:正确,
控制器:功能(MyService,$scope){
$scope.MyData=$scope.MyData | |{};
MyService.getData().then(函数(值){
$scope.MyData.value=值;
});
},
链接:函数(范围、元素、属性){
scope.MyData=scope.MyData | |{};
}
};
});
看看这把小提琴:这项任务可以用各种方式完成,但问题是哪种做法最好。 首先,如果您有一个带有partial的指令,并且希望绑定到它,那么可以在该指令的控制器中进行绑定
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
};
});
希望这有帮助
一些在线资源可能会有所帮助:
我认为最好立即在控制器中调用函数,而不是将其放入ng init中。如果您输入ng init,它将在div被渲染时被调用,但我不认为这有什么帮助。@sniels谢谢您的输入,您的推理是有意义的。我需要自己尝试这种方法。我认为链接函数在这种情况下是无用的,如果$scope.myData已经有值,我只需删除链接函数和控制器中的检查。您也错误地使用了scope选项,可能应该删除它。除此之外,这似乎是一个很好的答案。@sniels关于link你是对的:多余的。。。关于作用域,你错了:@malix我不认为他错了,controller和link的作用域是相同的,即使是隔离的。不同的是,控制器是在渲染前执行的,链接是在渲染后完成的,所以在链接函数中,您应该执行所有的DOM操作。查看我的plunker@maurycy我知道。。。我的回答是“您也错误地使用了scope选项,应该删除它。”而
scope:true
在文档中显然是允许的……您应该在服务的回调函数中操作数据。基本上,在设置scope.myData之前。在控制器中执行此操作应该没有问题,因此我建议您将其放在那里,因为链接函数用于不同的原因。如果您可以将控制器从不必要的逻辑中剥离出来,则这是最佳做法。控制器是视图的驱动者,服务和工厂是放置额外逻辑的地方,比如数据操纵,正好@maurycy。谢谢你的评论和支持答案。直截了当。正是我需要的。非常感谢。