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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了保持我的代码DRY为`$ onInit`和`$ onChanges`方法相关的知识,希望对你有一定的参考价值。

我有一段代码在几乎所有组件中重复:

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变量,这是我的观点所特有的。

我怎样才能让它干涸?做一个基类?用装饰器?

答案

我认为有很多不同的方法,但如果你坚持使用类和继承,你可以将_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
        });
    }
}

以上是关于保持我的代码DRY为`$ onInit`和`$ onChanges`方法的主要内容,如果未能解决你的问题,请参考以下文章

MVC 验证 - 使用服务层保持 DRY - 最佳实践是啥?

在 Gatsby 中使用 GraphQL 获取许多图像时如何保持 DRY

在 React Native 中使用 TextInput 等组件在样式方面保持 DRY 的最佳实践?

如何使用 Django 模型字段定义保持 DRY

在不更改架构的情况下保持 XML DRY

Angular 1.5 $onInit 未触发 - 打字稿