I have following 2 directives. In DirectiveA
I am getting some data from remote server and then rendering a template with that data as anchor
tag. Now when user click on any of the link, I broadcast
event and listen to that event in DirectiveB
. In DirectiveB I want to make another ajax request and when I receive response with data then I want to render DirectiveB
template. My current approach does not work because it executes both of the Directives in the beginning and at that time I do not have any data for DirectiveB
. Below is the code
DirectiveA
angular.module('app').directive('DirectiveA', function ($http) {
'use strict';
return {
restrict: 'E',
templateUrl: '/templates/templateA.html',
controller: function ($scope) {
$scope.showDetails = function (num) { // <-- this executes in ng-click in template
$scope.$broadcast('season', num);
};
},
link: function (scope, element, attributes) {
$http.get(attributes.resource).then(function (response) {
scope.rows = response.data;
scope.seasons = [];
for (var i = 0; i < scope.rows.length; i++) {
var num = parseInt(scope.rows[i].data);
if (year >= 2005 && year <= 2015) {
scope.seasons.push({ 'data': scope.rows[i].data });
}
}
});
}
};
});
Here is DirectiveB
angular.module('app').directive('DirectiveB', function() {
return {
restrict: 'E',
templateUrl: 'templates/templateB.html',
controller: function($scope, $http) {
$scope.$on('season', function ($scope, num) { // I listen to that event
$http.get('http://demo.com/api/' + num).then(function (response) {
$scope.standings = response.data;
});
});
}
};
});
UPDATE
Here is how I am using it in HTML
<directive-a resource="http://demo.com/api/>
</directive-a>
<directive-b></directive-b>
UPDATE
I am still waiting for its solution.
UPDATE 3
templateA
<ul>
<li ng-repeat="row in seasons">
<a href="#" ng-click="showDetails(row.season)">{{ row.season }}</a>
</li>
</ul>
Template B
<h3>Standings</h3>
<table>
<thead>
<th ng-repeat="standing in standings" ng-if="state">{{ position }}</th>
</thead>
<tbody>
<tr ng-repeat="row in standings">
{{ row.Driver }}
</tr>
</tbody>
</table>
Your question boils down to:
How to ensure the communication between DirectiveA
and DirectiveB
As both your directives use the same scope, your solution with event broadcasting works. This would break once you change the scope
setting inside DDO to anything else but false
.
That's why I'd advise you $broadcast
the event on $rootScope
.
How to render DirectiveB
's template once data is ready
A simple ngIf
wrapping the directive's template would do the job. We don't need anything fancy for this.
Bellow is a simple working example. Notice how both directives use an isolated scope - this is just to showcase why you need $rootScope.$broadcast
. I'm also using $timeout
in order to simulate the server's latency.
angular
.module('myApp', [])
.directive('directiveA', function() {
return {
templateUrl: 'tempA.html',
controller: function($rootScope, $scope) {
$scope.sendMessage = function(message) {
$rootScope.$broadcast('eventName', message);
};
},
scope: {}
};
})
.directive('directiveB', function() {
return {
templateUrl: 'tempB.html',
controller: function($rootScope, $scope, $timeout) {
$scope.messages = [];
$rootScope.$on('eventName', function(event, message) {
$timeout(function() {
$scope.messages.push(message);
}, 50);
});
},
scope: {}
};
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<div ng-app="myApp">
<directive-a></directive-a>
<directive-b></directive-b>
<script type="text/ng-template" id="tempA.html">
<h2>Hello from DirectiveA</h2>
<label>
<p>Message to send to DirectiveB</p>
<input type="text" ng-model="toSend">
</label>
<button type="button" ng-click="sendMessage(toSend); toSend = '';">Send</button>
</script>
<script type="text/ng-template" id="tempB.html">
<div ng-if="messages.length > 0">
<h3>Hello from DirectiveB</h3>
<ul>
<li ng-repeat="message in messages track by $index">{{ message }}</li>
</ul>
</div>
</script>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With