David Casillas
David Casillas

Reputation: 1911

How to share AngularJS controller with several components having custom behavior

In AngularJS >1.5, how can several related components share a common controller with common functionallity while being able to have custom behavior for every distinct component?

For example implementing components for <input> elements of different types (text, number, date ... ), every controller will share the same functionallity (to propagate the component value to parent on value changes for example) so one can write a function for the controller and use it on all of them. But if a custom behavior is needed for some types. How can it be detected which component does the controller belong?

Here is some psudo-code:

var commonController = function() {

    this.$onInit = function() {
        // common code for all types

        // code for a specific type
        // how can I detect here which component is running?
    }
}

angular.module('app')
.component('component01', {
    controller: commonController),
    ...
})
.component('component02', {
    controller: commonController),
    ...
})
.component('component03', {
    controller: commonController),
    ...
})

Upvotes: 0

Views: 357

Answers (1)

rdrw
rdrw

Reputation: 793

I think you can accomplish this by combining all the desired input types into a single common-input component and providing the type as a binding to the component. Then within your CommonController you can display/handle changes based on the set input-type.

I have included a snippet below that should accomplish what something similar to what you are looking for. Notifying the parent component would take adding a callback handler to your bindings that you can pass the updated value and input type to.

angular.module('tester', []);

angular.module('tester').component('commonInput', {
  bindings: {
    inputType: '<'
  },
  controller: CommonController,
  template: `
    <div ng-switch on="$ctrl.inputType">
      <input ng-switch-when="text" type="text" ng-model="$ctrl.text" ng-change="$ctrl.onTextChange()"/>
      <input ng-switch-when="date" type="date" ng-model="$ctrl.date" ng-change="$ctrl.onDateChange()"/>
      <input ng-switch-when="number" type="number" ng-model="$ctrl.number" ng-change="$ctrl.onNumberChange()"/>
    </div>
  `
});

function CommonController() {
  this.$onInit = function() {
    console.log('input type:', this.inputType);
    this.text = '';
    this.date = null;
    this.number = null;
  };
  
  this.onTextChange = function() {
    console.log(this.text);
  };
  
  this.onDateChange = function() {
    console.log(this.date);
  };
  
  this.onNumberChange = function() {
    console.log(this.number);
  };
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.js"></script>

<div ng-app="tester">
  <common-input input-type="'text'"></common-input>
  <common-input input-type="'date'"></common-input>
  <common-input input-type="'number'"></common-input>
</div>

Upvotes: 1

Related Questions