AngularJs – Directive events and dom rendering-Collection of common programming errors

In the code below, I am trying to use a template (with {{ value }} substitution) but I have been trying for two days to find a way of getting to the rendered code to set some properties on it.

I cannot use the style selector (which works fine), I need to use the div’s id. In my real code I use a templateUrl: not the inline code, but it has the same result.

Which event should I be listening for? At what point in time will the selectors work? I have read about compiling and linking and think the answer is out there somewhere?

Thanks in advance …




  
  My AngularJS App

  





    

  
  
  
  
  
  

  



var coreDirectives = angular.module('tlsCore.directives', []);

coreDirectives.directive('tlsWindow', function() {
  return {
    restrict: 'E',
    scope:  {
        windowId: '@windowId',
        windowWidth: '@windowWidth',
        labelWidth: '@windowLabelWidth'
    },
    replace: true,
    transclude: false,
    template: '  ' +
        '' +
            '' +
                '' +
                '' +
            '' +
        '',
    link: function (scope, element, attrs) {

        var ele = element.get(element.index(scope.windowId));

        // this works and sets the colour (by class)
        $('.tls-window-toolbar-content').css ("background-color",  'red');

        // this does not work as the id of the element is not yet substituted and rendered ??
        $('#fred-winBackground').css ("background-color",  'green');

    }   
  }
}); 





  1. Instead of using the template method, move the HTML into the link method. This enables us to manually $interpolate the bracketed terms before compiling, and then use the ID selector. Note that this would not be possible without using the = instead of @ isolate scope binding, because @ bindings are postponed until later and are undefined in the link method (See more on that here).

    app.directive('tlsWindow', function($interpolate,$compile) {
      return {
        restrict: 'E',
        scope: {
            windowId: '=',
            windowWidth: '=',
            labelWidth: '='
        },
        link: function (scope, element, attrs) {
            var template = '' +
            '' +
                '' +
                    '' +
                    '' +
                '' +
            '';
    
            var interpolated = $interpolate(template)(scope);
            var html = $(interpolated);
            element.replaceWith($compile(html)(scope));
    
            $('.tls-window-toolbar-content').css('background-color', 'red');
            $('#fred-winBackground').css('background-color', 'green');
        }   
      }
    }); 
    

    Here is a fiddle

    Not the most robust solution but this would work also. Here the manipulation is postponed until after the rendering by using $timeout. This causes a slight delay as well.

    $timeout(function(){
        $('#fred-winBackground').css("background-color", 'green');
    },0);
    

    This requires $timeout to be injected into the directive as well.

Originally posted 2013-12-02 01:31:31.