Reputation: 2588
Having trouble getting a directive to display properly with data that is updated via promise. The first directive updates perfectly, but the second and third do not.
First, the data:
app.controller('MainCtrl', function($scope, $timeout) {
$scope.data = {};
$timeout(function() {
angular.copy({totalItems: 100, pageSize: 10, currentPage: 1 }, $scope.data);
}, 3000);
});
Then the directives:
var template1 = '{{(data.pageSize * (data.currentPage - 1)) + 1}} - {{data.pageSize * data.currentPage}} of {{data.totalItems}}';
var template2 = '{{lower}} - {{upper}} of {{total}}';
var dir = {
restrict: 'C',
template: template1,
scope: false
};
app.directive('pagination', function() {
return dir;
});
app.directive('pagination2', function() {
dir.template = template2;
dir.link = function(scope, element, attrs) {
scope.lower = (attrs.size * (attrs.currentPage - 1)) + 1;
scope.upper = (attrs.size * attrs.currentPage);
scope.total = attrs.total;
};
return dir;
});
app.directive('pagination3', function() {
dir.template = template2;
dir.link = function(scope, element, attrs) {
scope.lower = (scope.data.pageSize * (scope.data.currentPage - 1)) + 1;
scope.upper = (scope.data.pageSize * scope.data.currentPage);
scope.total = scope.data.totalItems;
};
return dir;
});
And lastly the markup:
<div class="pagination"></div>
<div class="pagination2" total="{{data.totalItems}}" size="{{data.pageSize}}" current-page="{{data.currentPage}}"></div>
<div class="pagination3"></div>
I understand why the first one works. The $timeout
finishes, my $scope
is updated, dirty check ensues, everything is recalculated, and all is well.
In the second one I think I understand why it doesn't update - because the data is not there when I pass values to the element attributes, meaning the entire directive is built using undefined
values. I would like to somehow correct this and have the directive update when $scope.data
updates.
I figured I'd solve the problem I was having with the second directive with the third directive but am quite confused why this one doesn't work. I thought I had direct access to the $scope
because my directive is using scope: false
, but apparently not.
Upvotes: 0
Views: 37
Reputation: 5270
app.directive('pagination3', function() {
dir.template = template2;
dir.link = function(scope, element, attrs) {
scope.lower = (scope.data.pageSize * (scope.data.currentPage - 1)) + 1;
scope.upper = (scope.data.pageSize * scope.data.currentPage);
scope.total = scope.data.totalItems;
};
return dir;
});
Per your code, you are assigning scope.data.totalItems
at directive's linking phase but at that time scope.data
is just an empty object {}
, it has no property called totalItems
or pageSize
or currentPage
. lower, upper and total will be undefined
after the assignment.
If you really don't want to put the calculation in your view template, you can monitor scope.data
's change as below
app.directive('pagination3', function() {
dir.template = template2;
dir.link = function(scope, element, attrs) {
scope.$watch('data', function(newVal, oldVal) {
scope.lower = (newVal.pageSize * (newVal.currentPage - 1)) + 1;
scope.upper = (newVal.pageSize * newVal.currentPage);
scope.total = newVal.totalItems;
}, true);
};
return dir;
};
Upvotes: 1