Reputation: 4083
UPDATE
My controller loads data from two services, and the directive is linked before one of the services has returned data. So I think I need to find a way to prevent loading the directive until the variable from the second service has actually been populated.
What is the best way to handle that?
Original question:
I have a scope with an array of objects, and also a single integer. So, in the controller, something like this:
$scope.array = [
{title: 'foo', first: 'spam', second: 'eggs'},
{title: 'bar', first: 'maps', second: 'sgge'}
];
$scope.another = 400;
I am using ngRepeat to pass values from each object in the array to a directive, like so:
<div ng-repeat="a in array"
my-directive="a.title"
my-first-val="a.first"
my-second-val="a.second"></div>
I would also like to bind another value, which is the same for all instances of the directive, but may also change:
<div ng-repeat="a in array"
my-directive="a.title"
my-first-val="a.first"
my-second-val="a.second"
another-val="another"></div>
This final value never seems to bind properly [actually, it didn't bind because it hadn't populated yet - the syntax used here is fine]. Is this possible? Is there another way to bind a single value to all instances of a directive using ngRepeat?
Upvotes: 1
Views: 494
Reputation: 589
To answer your updated question, I suggest you to use a $q promise. You could use a promise for loading the data of each service, and then the all
method to combine the 2.
var promise1 = arrayService.getArray();
var promise2 = anotherService.getAnother();
var promise = $q.all([promise1, promise2]);
promise.then(function(data) {
$scope.array = data[0];
$scope.another = data[1];
});
EDIT: I understand from your comment that you want to know how to return a promise with a service. Code in 'arrayService' service
angular.module('yourApp').service('arrayService', function($q, someAsyncService) {
this.getArray = function() {
var deferred = $q.defer();
someAsyncService.get(function(err, data){
if (err) {
deferred.reject(err);
}
else {
deferred.resolve(data);
}
});
return deferred.promise;
};
});
Upvotes: 4
Reputation: 1036
in response to the updated question one approach you could take if you have access to the directive and can change it is to add a scope.$watch to the another-val attribute in the link or controller function
scope.$watch('anotherVal', function(newVal) {
//do something here...
});
Upvotes: 0
Reputation: 1036
You might want to try to use expression evaluation with double braces
<div ng-repeat="a in array"
my-directive="a.title"
my-first-val="a.first"
my-second-val="a.second"
another-val="{{another}}"></div>
angular would then try to evaluate the expression from the $scope instead of looking for the another variable from within the child scope created by ng-repeat
Upvotes: 0
Reputation: 589
ng-repeat
creates a child scope, so you're another
is different in every child scope.
I would try defining another
as the property of an object:
$scope.whatever.another = 400
html:
<div ng-repeat="a in array"
my-directive="a.title"
my-first-val="a.first"
my-second-val="a.second"
another-val="whatever.another"></div>
Upvotes: 2