Reputation: 6763
Is it possible to manually recompile a directive nested inside another directive?
I have a modal-create-task
directive that is initialized using a showCreateTaskModal
event together with some data. Based on the data coming with the event the modal change its UI layout and also changes the behavior of a nested directive called search-projects
.
The problem I'm having at the moment is that I need to recompile the search-directive
because it needs the data coming in with showCreateTaskModal
is fired.
This is how the modal template looks like:
<div class="ui modal" id="modalCreateTask" ng-controller="ModalCreateTaskCtrl">
<search-projects oo-filter="{{ mode }}" oo-subject="searchProjectSubject"></search-projects>
</div>
As you can see both the oo-filter
and oo-subject
attributes are depending on the data attached to the showCreateTaskModal
event, but that event is fired only after the compiler goes through the DOM and then the directive has no access to the needed data, so it falls back to default behavior.
This is the search-projects
definition:
angular.module('app.ui.search.projects').directive('searchProjects', function(ConfigService)
{
return {
restrict : 'E',
templateUrl : ConfigService.path.views + '/search/projects.html',
scope : {
filter : '@ooFilter',
subject : '=ooSubject'
}
}
});
Edit 1:
As per request I'll try to explain better what I'm doing.
I have a modal that contains another directive that, based on the content of certain variables, should query the server for data whenever the attributes are changing.
I wanted to recompile the directive in order to execute the init()
function again.
Making some researches I also noticed that it's possible to use $watch
but I don't know if that's a good solution.
Upvotes: 1
Views: 179
Reputation: 49590
It is quite rare that a directive requires recompiling. This could be indicative of a wrong approach or design.
Directives react to data. Typically, data is passed to a directive via attributes, or broadcasted events, or a shared service with the controller. Specifically, isolate scope uses one- and two- way data binding to pass data to the directive.
In absence of a different trigger, one could $watch
for changes:
link: function(scope){
scope.$watch("scopeVar", function(){
// do something, like run init() again
});
}
Another alternative is via direct trigger from a service, similar to how Angular-UI $modal service works. The modal instance exposes a method, for example, to close the modal (directive) from the controller:
modalInstance.close(result);
This idea could be similarly used to trigger some actions in the directive that uses the same service.
Upvotes: 2
Reputation: 2737
Attach an 'ng-if' condition to your 'search-projects' directive based on the data that is coming from your event. So your code might look like this :
<div class="ui modal" id="modalCreateTask" ng-controller="ModalCreateTaskCtrl">
<search-projects oo-filter="{{ mode }}" oo-subject="searchProjectSubject"
ng-if="dataComingFromEvent"></search-projects>
</div>
The directive will be put again in the DOM when the data is available in the 'model' viz 'dataComingFromEvent' and hence your directive will be recompiled.
Upvotes: 1