Reputation: 1897
I have a directive that has a controller with a $http call to an endpoint. I'd like to take the results of that server call and then display them in my template. If I have a single value inside my template, and then set it explicitly, it all works fine. If I try to bind the template to the server call then I get the error mentioned above. Do I need to use the $compile service for this to work?
thanks in advance
Final result with compilation
function mydirective(myservice,$compile) {
return {
restrict: 'ACE',
scope: {
url: '=',
title: '=',
},
controllerAs: 'ctrl',
bindToController: true,
controller: ['$scope', function($scope) {
myservice.init('http://jsonplaceholder.typicode.com/posts')
.then(function(data) {
$scope.postRequest(data);
});
$scope.postRequest = function(val) {
this.items = val;
this.title = val[0].title;
};
}],
link: function ($scope, $el, $attr ) {
var template = '<div class=\"test\">{{this.title}}</div>' +
'<div class=\"tes\" ng-repeat=\"item in this.items\">'+
'<div class=\"test1\">{{item.title}}</div>'+
'</div>';
var e = $compile(template)($scope);
$el.after(e);
}
};
}
Upvotes: 0
Views: 871
Reputation: 22323
Here is a refactored version of your directive. Because you are using controllerAs
, the reference to $scope
can be removed entirely. Also, a variable ctrl
is created as an alias to the controller, for consistent access to the controller from inside callback functions. Finally, the link
function is removed and the template
has been adjusted to reference ctrl
instead of this
.
The error
RangeError: Maximum call stack size exceeded
is a result of using this
in the template, which is referring to the DOM rather than the controller, in conjunction with $compile
, essentially compiling the DOM into itself.
function mydirective(myservice, $compile) {
return {
restrict: 'ACE',
scope: {
url: '=',
title: '=',
},
controllerAs: 'ctrl',
bindToController: true,
controller: function() {
var ctrl = this; //alias reference for use inside controller callbacks
myservice.init('http://jsonplaceholder.typicode.com/posts')
.then(function(data) {
ctrl.postRequest(data);
});
ctrl.postRequest = function(val) {
ctrl.items = val;
ctrl.title = val[0].title;
};
},
template: '<div class=\"test\">{{ctrl.title}}</div>' +
'<div class=\"tes\" ng-repeat=\"item in ctrl.items\">' +
'<div class=\"test1\">{{item.title}}</div>' +
'</div>'
};
}
Please note this code hasn't been tested.
Upvotes: 1