将我的代码保持为$ onInit和$ onChanges方法的DRY

时间:2018-08-20 19:40:38

标签: javascript angularjs ecmascript-6 dry angularjs-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]];
                        }
                    });
            }
        };
    }
}

唯一不同的是_generalProperties变量,该变量特定于我的视图。

如何使其保持干燥? 做基础课?使用装饰器?

1 个答案:

答案 0 :(得分:2)

我认为有很多不同的方法,但是如果您坚持使用类和继承,则可以向父构造函数提供_generalProperties并重用整个实现。

例如:

export class BaseSettingsComponent {
    constructor(properties){
        this._properties = properties;
    }

    $onInit(){ /* ... implement base component stuff*/ }
}

然后,在使用相同组件逻辑的每个页面上,您可以扩展基类,将属性提供给父类,然后让基类完成工作。

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*/ }
}

使用这种方法时要牢记的一件事是,如果您需要在子类上实现$onInit$onChanges,则必须调用super.$onInit(),否则将会失败父行为(由于覆盖)。

最后,对于更简洁的代码,您也可以舍弃_generalProperties的声明,直接将其提供给super构造函数。

import { BaseSettingsComponent } from '../common/base-settings-component.js';

export class GeneralDeviceSettingsCtrl extends BaseSettingsComponent {
    constructor(){
        super({
            'deviceName': deviceCommands.NAME.key,
            'deviceModel': deviceCommands.MODEL.key
        });
    }
}