title: AngularJS directive with two-way binding and ng-change
body: <p>I have come across a situation where I need to change the input type of an input box based on the selected value of a dropdown. In other words, if the user selects 'String' from the dropdown then the type of the input should be 'text', etc. I decided to create a directive cuz I'm still learning Angular but also so I don't copy blocks of code all over the place (I need this more than once).</p>
  
  <p>This it the contents of my attempt:</p>
  
  <pre><code>(function () {
      "use strict";
  
      angular
          .module('app')
          .directive('dynamicTypeInput', dynamicTypeInput);
  
      function dynamicTypeInput() {
          return {
              replace: true,
              restrict: 'AE',
              require: ['ngModel', '^form'],
              scope: {type: '=', placeholder: '@'},
              templateUrl: 'app/common/dynamic-type-input/dynamic-type-input.tpl.html',
              link : function(scope, element, attrs, ngModel){
  
                  //Watch for changes to ngModel, update scope.inputValue
                  scope.$watch(function(){
                      return ngModel[0].$modelValue;
                  }, function (value){
                      scope.inputValue = value;
                  });
  
                  //Watch inputValue, update the model
                  scope.$watch('inputValue', function(value){
                      ngModel[0].$setViewValue(value);
                  });
  
                  //Setup ng-change
                  if (attrs.ngChange) {
                      ngModel[0].$viewChangeListeners.push(function () {
                          scope.$eval(attrs.ngChange);
                      });
                  }
              }
          };
      }
  })();
  </code></pre>
  
  <p>Note: The template is simply an <code>ng-switch</code> that selects the appropriate input box based on the value of <code>scope.type</code> and the inputs all bind to <code>scope.inputValue</code>.</p>
  
  <p>I used the answer from <a href="https://stackoverflow.com/questions/24754005/how-to-implement-an-ng-change-for-a-custom-directive">this</a> SO question to help me add the ability to add an ng-change attribute and fire correctly. According to that answer I needed to remove the ngModel from the isolated scope, I'm not sure why this is required but, if someone could explain it I'd be grateful.</p>
  
  <p>Removing ngModel from the isolated scope made it more difficult to instantiate directive with an initial value or have the directive update when the model is changed in the main controller so now I watch <code>ngModel[0].$modelValue</code> and update the local value if it changes.</p>
  
  <p>While the directive works and does what I expect it do but it all seems a bit convoluted and inefficient, is there no way I can achieve what I want in a more simple manner?</p>