René Olivo
René Olivo

Reputation: 181

recompiling angular directive to add ng-module and ng-change programmatically

I want to know if I'm doing something right.

Preamble: I have developed a Typeahead class that consumes a resource and stores the results within itself. The class has more or less the following structure:

The issue is that if I want to attach all the required properties to an input, the code looks bloated:

<input 
  type="text"
  ng-model="myTa.input"
  ng-change="myTa.change();"
  ng-keyup="myTa.cursor()"
  .... 
/>

What I wanted to accomplish was a directive that would only need the Typeahead instance and it will attach all required properties to the element automatically. For example:

<input type="text" my-typeahead="myTa" />

Before continuing, I want to make clear the following:

Now, will I burn in hell if I do this:

angular
.module('myTypeaheadDirective', [])
.directive('myTypeahead', function($compile, $rootScope) {
    return {
        restrict: 'A',
        scope: {
            typeahead: '=myTypeahead'
        },
        compile: function() {
            return {
                pre: function precompile(scope, element, attrs) {
                    var installedAttribute = 'my-typeahead-installed';

                    if ( angular.isUndefined( element.attr( installedAttribute ) ) ) {
                        element.attr('ng-model', 'typeahead.input');
                        element.attr('ng-change', 'typeahead.change()');
                        element.attr( installedAttribute, true );
                        $compile(element)(scope.$parent);
                    }
                }
            }
        }
    }
});

To explain the code:

The directive pre compile process checks if it has already been installed, otherwise it will break into an infinite loop.

Inside the condition I add as many directives as I want.

Notice that I'm using ng-model="typeahead.input" but that's an isolated scope so I can have multiple inputs with different typeahead instances.

After attaching the new directives, I use the $compile service to recompile the element using the parent scope (so it can access the original typeahead instance).

My questions are:

Thank you very much for taking your time :)

Upvotes: 1

Views: 1023

Answers (1)

charlietfl
charlietfl

Reputation: 171700

Since what you are passing into the isolated scope can just as easily be used just from the attribute value ...could remove the isolated scope and then directive scope would be that of parent.

To set the typeahead object from attribute only could do:

var typeahead= attrs.myTypeahead;
element.attr('ng-model', typeahead+'.input');

Upvotes: 0

Related Questions