I have a piece of code that is repeated in almost all of my components:
import {deviceCommands} from "../../../core/data/Commands";
let _generalProperties = {
'deviceName': deviceCommands.NAME.key,
'deviceModel': deviceCommands.MODEL.key
};
export default class GeneralDeviceSettingsCtrl {
constructor($scope) {
let $ctrl = this;
$ctrl.$onChanges = function (changes) {
for(let prop in _generalProperties) {
$ctrl[prop] = $ctrl.test.vm.data[_generalProperties[prop]];
}
};
$ctrl.$onInit = function () {
for(let prop in _generalProperties) {
$scope.$watch(() => $ctrl.test.vm.data[_generalProperties[prop]],
(newValue, oldValue) => {
if (newValue !== oldValue) {
$ctrl[prop] = $ctrl.test.vm.data[_generalProperties[prop]];
}
});
}
};
}
}
The only thing that is different is the _generalProperties
variable, which is specific to my view.
How can I do to keep it DRY? Make a base class? use decorators?
I think there is plenty of different approaches to this but if you stick with classes and inheritance you can supply the _generalProperties
to your parent constructor and reuse the whole implementation.
For example:
export class BaseSettingsComponent {
constructor(properties){
this._properties = properties;
}
$onInit(){ /* ... implement base component stuff*/ }
}
Then, on each of your pages that uses the same component logic you can extend the base class, provide the properties to the parent class and let the base class do the job.
import { BaseSettingsComponent } from '../common/base-settings-component.js';
let _generalProperties = {
'deviceName': deviceCommands.NAME.key,
'deviceModel': deviceCommands.MODEL.key
};
export class GeneralDeviceSettingsCtrl extends BaseSettingsComponent {
constructor(){
super(_generalProperties);
}
$onInit(){ super.$onInit(); /* ... implement base component stuff*/ }
}
The one thing important to keep in mind when using this approach is that if you need to implement $onInit
or $onChanges
on the child classes you have to call the super.$onInit()
otherwise you lose the parent behavior due to an override.
Finally, for an even cleaner code, you can also discard the declaration of _generalProperties
supplying it directly into the super
constructor.
import { BaseSettingsComponent } from '../common/base-settings-component.js';
export class GeneralDeviceSettingsCtrl extends BaseSettingsComponent {
constructor(){
super({
'deviceName': deviceCommands.NAME.key,
'deviceModel': deviceCommands.MODEL.key
});
}
}