Search code examples
javascriptangularjsangularjs-directiveangular-ngmodelangularjs-ng-transclude

Angularjs directive add directives as attribute and bind them dynamically


Hi i am working on directive where i need to edit DOM add ng-src attribute and a model to it.

This is my DOM

     <edit-component>
      <img src="images/logo.png" title="Hearty Wear" />
    </edit-component>

I need the result DOM be

       `<div>
         <img src="images/logo.png" title="Hearty Wear" ng-src={{myModel}} />
       </div> `

Such that when i update myModel with data the image should be updated

UPDATE

sam.directive('editComponent', function() { return { restrict: 'EA', transclude: true, replace: true, templateUrl: "imageTemplate.html", link: function(scope, element, attb, ctrl, transclude) { scope.data = function() { var imagedata; imagedata = arguments[5]; scope.imageModel = imagedata.base64; return element.find('img').attr('src', "data:image/png;base64," + imagedata.base64); }; } }; });

I need the previous src attribute value also to display the existing image.

Right now im updating the src attribute manually.I need solution where i can update via model variable

Thanks


Solution

  • After a long reading of documentation about AngularJS Directives in various blogs and sites.

    I just came to know complete flow of directives

    The flow will be from

    Compile -> Controller -> preLink -> postLink or (Link)

    If you want add any core Directives of angular(ng-model, ng-style,ng-src) at Compile Phase

    var app;
    
    app = angular.module('App', []);
    
    app.directive('myDirective', [
      '$compile', function($compile) {  // Crucial Part
        return {
          scope: true,
          compile: function(element, attrs) {
            element.attr('ng-src', '{{imageModel}}');
            element.attr('ng-click', 'updateImage()');
            element.removeAttr('my-directive'); // Crucial Part
            return {
              pre: function(scope, ele, attb) {},
              post: function(scope, ele, attb) {
                $compile(ele)(scope);
                return scope.updateImage = function() {
                  return scope.imageModel = "http://www.google.com/logos/doodles/2015/halet-cambels-99th-birthday-6544342839721984-hp2x.png";
                };
              }
            };
          },
          controller: function($scope, $element, $attrs) {
            return $scope.imageModel = null;
          }
        };
      }
    ]);
    <!DOCTYPE html>
    <html>
    <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
      <meta charset="utf-8">
      <title>JS Bin</title>
      <style>
        img {
          max-width: 100%;
          
        }
      </style>
    </head>
    <body ng-app='App'>
      <img src="https://www.google.co.in/images/srpr/logo11w.png" alt="" my-directive>
    
    </body>
    </html>

    I will explain the necessary steps involved in it .

    First phase (Compile) :-

    Add the core angular directives or custom directives you want in this phase by

        element.attr('ng-src', '{{imageModel}}'); // For dynamic image url changes
        element.attr('ng-click', 'updateImage()'); // The trigger to update image
        element.removeAttr('my-directive'); // **Crucial step please remove your custom directive attribute**
    

    If you dont remove your Custom directive during $compile() it will loop infinite times

    Second phase (Controller):-

    Define all your models needed and function in these phase (I know i have defined updateImage() in postLink . It also works!)

    $scope.imageModel = null // Initialization

    Third phase (link) :- The order is first preLink and then postLink . I haven't defined anything in the prelink.

    postLink :- $compile(element)(scope). This will actually bind compile all the directives involved in the element and it binds them dynamically.(vola). Everything works as desired.

    Thanks. If you feel i have missed some points or misunderstood the concept, feel free to update it.

    JSBin link https://jsbin.com/parote/edit?html,js,output