Angular JS中的动态配置

时间:2015-11-17 12:03:35

标签: javascript angularjs

我正在创建一个显示图表的指令。 我经历了创建模块的常用模板,带有指令。对于配置,我决定使用Provider。 我明白了如何让应用程序通过提供程序设置我的模块配置。

但是,我遇到的一个用例是配置可以根据用户在运行时的首选项进行更改。 如何使我的模块能够为客户端API提供在运行时修改配置的方法?

是否可以将ProviderConfiguration注入客户端控制器?这种方法有任何明显的缺点吗?

当前的代码模板如下所示

//Provider
angular.module('foobar', []).provider('foobarConfig', [function() {
    var config = {
        //config properties here.
    }
    var configurationProvider = {
        //Getters and Setters that work on 'config'.
        setProperty(prop, value) {
            if(config[prop] !== undefined) {
                config[prop] = value;
            }
        },
        getProperty(prop) {
            return config[prop];
        },
        $get: function() {
            return this;
        }
    }
    return configurationProvider;
}

//Chart Directive.
angular.module('foobar').directive('foobarChart', ['foobarConfig', function(foobarConfig) {
    //Can use the foobarConfig here.
}]);

angular.module('clientApp', [ 'foobar'])
.config(['foobarConfigProvider', function(foobarConfigProvider) {
    //Can provide the initial configuration to the module here.
    foobarConfigProvider.setProperty("foo", "bar");
}]);

angular.module('clientApp').directive('clientFoo', function() {

    //What should be done to change foobarConfig here?
});

1 个答案:

答案 0 :(得分:1)

是的,它是完全有效的配置服务配方,可在配置阶段和运行阶段使用,因此可以以相同的方式使用foobarConfigProvider.setProperty("foo", "bar")foobarConfig.setProperty("foo", "bar")

对于没有依赖关系的配置服务constant是更方便的选择:

.constant('foobarConfig', (function () {
    var config = {
        // ...
    };

    return {
        setProperty: function (prop, value) {
            if(config[prop] !== undefined) {
                config[prop] = value;
            }
        },
        getProperty: function (prop) {
            return config[prop];
        }
    };
})());

对于配置密钥有限的ES5兼容解决方案,可以使用constant Object.definePropertyObject.seal的对象,这样就无需使用自定义getter / setter功能。 Object.defineProperty可以在初始config对象上进行迭代,因此不需要样板描述符代码:

.constant('foobarConfig', (function () {
    var config = {
        // ...
    };

    var obj = {};

    angular.forEach(config, function (value, key) {
        Object.defineProperty(obj, key, {
            enumerable: true,
            writable: true,
            value: value
            // no 'get' and 'set' are required if the only purpose for
            // them is to restrict a set of config keys
        })
    });

    Object.seal(obj);

    return obj;
})());

请注意,这里constant的主要区别(和可能的缺点)是急切地定义服务值,foobarConfig将是不同注入器的相同对象。通常生产没有差异,但这可能(或可能不会)影响测试。