Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically adding Angular directives

I'm fairly new to angular JS and am finding it a steep learning curve, I get the feeling im really missing the point here but here goes:

I want to add a directive to my page from a controller. So I thought if I add the directive tag to the page, the directive and associated controller/template etc get added with it. After reading about the $compile method, I thought this would then be used to bind this directive to its newly created tag. This part is commented out below, but with or without this, I need the word login to appear and its controller to control it?

I can find lots of examples of similar around the web when the directive tag is on the page at load time, and can get those to work fine, so this is whats making think it is related to the $compile method - what am I missing?

HTML:

<div ng-app="application" ng-controller="myController"></div>

JS:

var myApp = angular.module('application', []);

myApp.controller('myController', ['$scope', function($scope) {

        function showLoginDirective () {
            $scope.login = angular.element(document.createElement('login'));

            angular.element(document.body).append($scope.login);
        };

        showLoginDirective();
    }
]);

angular.module('directives', [])
    .directive('login', function($compile) {
        return {
            restrict: 'E',
            controller: 'LoginController',
            template: '<div>login</div>',
            link: function(scope, element, attrs) {
                //$compile(element.contents())(scope.$new);
                console.log('should I not have a div containing login controlled by loginController at this point?');
            }
        };
});

the above code is also here: http://jsfiddle.net/d5n6L/7/

like image 690
alfonsob Avatar asked Dec 09 '13 22:12

alfonsob


People also ask

Can we import directives in angular?

You can put commonly used directives, pipes, and components into one module and then import just that module wherever you need it in other parts of your application. Notice the following: It imports the CommonModule because the module's component needs common directives.

What is dynamic components in angular?

What dynamic components are. Dynamic means, that the components location in the application is not defined at buildtime. That means, that it is not used in any angular template. Instead, the component is instantiated and placed in the application at runtime.

Which service allows us to dynamically load a component in a certain position on the page?

Angular comes with its own API for loading components dynamically.

How do you create a dynamic component in angular 13?

Dynamically load components in Angular 12 and 13 In the html template, there is a with viewContainerRef. We use ViewChild('viewContainerRef') to obtain the ViewContainerRef. Moreover, we declare ComponentRef array to release the memory of FoodCardComponent in ngOnDestroy to avoid memory leaks.


2 Answers

You shouldn't really be dynamically adding elements to the page with Angular. Many people, myself included, who come from a jQuery background, assume that we can continue with this practice and just add things to the page as we need them.

However, with Angular, the logic should really all be visible in the markup. What does that mean? In your case, you should have the directive there no matter what, and then control its visibility with ng-show or ng-hide or ng-class.

So, something like this would be best:

<login ng-show="showLogin"></login>

And then you can use your directive as you programmed.

Note that you can also define an inline controller (assign an array of dependencies and a function of those dependencies as the controller property of your directive). That keeps all related code in the same place.

E.g.,

angular.module('directives', [])
    .directive('login', function($compile) {
        return {
            restrict: 'E',
            controller: ['$scope', function($scope) {

                function showLoginDirective () {
                    $scope.showLogin = true;

                };

                 showLoginDirective();
              }
            ],
            template: '<div>login</div>',
            link: function(scope, element, attrs) {
                //$compile(element.contents())(scope.$new);
                console.log('should i not have a div containing login controlled by loginController at this point?');
            }
        };
});
like image 162
jraede Avatar answered Sep 29 '22 11:09

jraede


Rather than compiling dynamically from within your controller I suggest you use ng-if to declaratively express which DOM elements should exist on the DOM.

HTML

<div ng-app="application" ng-controller="myController">
    <div ng-if="showLogin" login></div>
</div>

JS

var myApp = angular.module('application', []);

myApp.controller('myController', ['$scope', function($scope) {

        function showLoginDirective () {
            $scope.showLogin = true;
        };

        showLoginDirective();
    }
]);

angular.module('directives', [])
    .directive('login', function($compile) {
        return {
            restrict: 'E',
            controller: 'LoginController',
            template: '<div>login</div>',
            link: function(scope, element, attrs) {
                //$compile(element.contents())(scope.$new);
                console.log('should i not have a div containing login controlled by loginController at this point?');
            }
        };
});
like image 23
eddiec Avatar answered Sep 29 '22 13:09

eddiec