siannone
siannone

Reputation: 6763

Recompile AngularJS nested directive

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

Answers (2)

New Dev
New Dev

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

Adarsh Konchady
Adarsh Konchady

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

Related Questions