Search code examples
angularjsangularjs-directiveangularjs-ng-modelangularjs-componentsangularjs-ng-change

How to add ng-model functionality to a component


Angular ng-change on ng-model passed into child directive

Basically, I want to be able to pass in ng-model from a parent directive to a child directive. I could just in a 2-way binded value, but then I wouldn't be able to use a ng-change in the parent directive on the child element. I could also use ng-click, but this wouldn't work with a non-clicking change (such as a text area instead of a checkbox). So I'm wondering if there's a way to allow a custom directives to have a ng-model/ng-change pair similar to how inputs, buttons, text areas and other html elements can. I want to avoid using emits, ons, watches, passing callbacks, etc. I just want to be able to do [input type="checkbox" ng-model="ngModel"] on a custom directive instead of input.

Parent Template

<child ng-model="x" ng-change="x()"></toggle>

Parent Directive

$scope.x = function() {console.log('hi')};

Child Template

<div>
     <input type="checkbox" ng-model="ngModel">
</div>

Child Directive ??

$scope.ngModel = $element.controller('ngModel'); 

My angular version is 1.4.8 btw.

Thanks :)


Solution

  • Almost the same as @georgeawg answer, but using directive method (since component was introduced in 1.5+, but author has 1.4.8):

    angular.module('myApp', [])
    .controller('MyCtrl', ['$scope', function MyCtrl($scope) {
    
    }])
    .directive('inputComponent', [function () {
            var myDirective = {
                restrict: 'E',
                require: 'ngModel',
                templateUrl: "checkboxComponent.html",
                link : function(scope, element, attrs, ngModelCtrl){
                    scope.updateModel = function(ngModel) {
                        ngModelCtrl.$setViewValue(ngModel);
                    }
                }
            }
            return myDirective;
    }]);
    fieldset {
      margin-top: 1em;
    }
    <script src="//code.angularjs.org/1.4.8/angular.js"></script>
    
    <div ng-app="myApp">
      <div ng-controller="MyCtrl">
        
        <input-component ng-model="value"
                         ng-change="value2=value"></input-component>
                         
                                            
        <fieldset>
          <p>value = {{value}}</p>
          <p>value2 = {{value2}}</p>
        </fieldset>
        
      </div>
      
      <script type="text/ng-template" id="checkboxComponent.html">
        <div>
             <input type="text" ng-model="ngModel" ng-change="updateModel(ngModel)" />
        </div>
      </script>
      
    </div>