hug*_*ige 5 javascript angularjs typescript angular
我想知道在angular2中设置可配置模块的最佳方法是什么.在angular1中,这通常是通过提供商完成的.随着它们的改变,你会如何将配置参数传递给可重用的ng2模块/指令/组件?
一个ng1的例子:
// configuring a (third party) module
.config(function (angularPromiseButtonsProvider) {
angularPromiseButtonsProvider.extendConfig({
spinnerTpl: '<div class="other-class"></span>',
disableBtn: false
});
});
// setting up the provider
.provider('angularPromiseButtons', function angularPromiseButtonsProvider() {
var config = {
spinnerTpl: '<span class="btn-spinner"></span>',
priority: 0,
disableBtn: true,
};
return {
extendConfig: function(newConfig) {
config = angular.extend(config, newConfig);
},
$get: function() {
return {
config: config
};
}
};
})
// using the result in the directive, etc.
.directive('promiseBtn', function(angularPromiseButtons){
var config = angularPromiseButtons.config;
})
Run Code Online (Sandbox Code Playgroud)
这基本上与这个问题相同,但针对的是angular2.
Est*_*ask 15
有几种配方,可以单独使用或一起使用.
通常需要具有以键/值形式提供必要配置的服务.
可能有多个配置服务来配置一个应用程序实体,例如,someConfig用于通用用户定义的配置,以及someDefaultConfig应该可能更改的所有默认值.例如,someConfig可能包含始终由用户定义的auth凭证,并且someDefaultConfig可能包含默认挂钩回调,auth提供程序的深层设置等.实现此目的的最简单方法是将配置对象与其合并Object.assign.
需要用户明确定义配置服务的配方,它基本上使用DI来指定某些模块在没有正确配置的情况下将无法工作.
AngularJS
// third-party module
// will fail if someConfig wasn't defined by the user
angular.module('some', []).factory('someService', (someConfig) => { ... })
// user-defined module
angular.module('app', ['some']).constant('someConfig', { foo: 'foo' });
Run Code Online (Sandbox Code Playgroud)
角
// third-party module
export const SOME_CONFIG = new InjectionToken('someConfig');
@Injectable
class SomeService {
constructor(@Inject(SOME_CONFIG) someConfig) { ... }
}
@NgModule({ providers: [SomeService] })
export class SomeModule {}
// user-defined module
@NgModule({
imports: [SomeModule],
providers: [{ provide: SOME_CONFIG, useValue: { foo: 'foo' } }]
)
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)
这是前一个配方的略微变化,唯一的区别是,如果用户未定义配置服务,则存在空的默认值,该值不会使应用程序失败:
AngularJS
// third-party module
angular.module('some', [])
.constant('someConfig', {})
...
Run Code Online (Sandbox Code Playgroud)
角
// third-party module
@NgModule({ providers: [..., { provide: SOME_CONFIG, useValue: {} }] })
export class SomeModule {}
...
Run Code Online (Sandbox Code Playgroud)
或者,可以使配置服务完全可选用于注射.
AngularJS
// third-party module
angular.module('some', []).factory('someService', ($injector) => {
const someConfig = $injector.has('someConfig') ? $injector.get('someConfig') : {};
...
})
...
Run Code Online (Sandbox Code Playgroud)
角
// third-party module
export const SOME_CONFIG = new InjectionToken('someConfig');
@Injectable
class SomeService {
constructor(@Inject(SOME_CONFIG) @Optional() someConfig) {
this.someConfig = someConfig !== null ? someConfig : {};
...
}
}
@NgModule({ providers: [SomeService] })
export class SomeModule {}
...
Run Code Online (Sandbox Code Playgroud)
forRoot静态模块方法是Angular路由器模块和众多第三方模块遵循的约定.如指南中所述,该方法返回一个实现的对象ModuleWithProviders.
基本上,它提供了基于forRoot(...)参数动态定义模块提供程序的机会.这可以被认为是AngularJS的替代config和providerAngular中不存在的单位.
AngularJS
// third-party module
angular.module('some', [])
.constant('someDefaultConfig', { bar: 'bar' })
.provider('someService', function (someDefaultConfig) {
let someMergedConfig;
this.configure = (config) => {
someMergedConfig = Object.assign({}, someDefaultConfig, config);
};
this.$get = ...
});
// user-defined module
angular.module('app', ['some']).config((someServiceProvider) => {
someServiceProvider.configure({ foo: 'foo' });
});
Run Code Online (Sandbox Code Playgroud)
角
// third-party module
export const SOME_CONFIG = new InjectionToken('someConfig');
export const SOME_DEFAULT_CONFIG = new InjectionToken('someDefaultConfig');
@Injectable
class SomeService {
constructor(
@Inject(SOME_CONFIG) someConfig,
@Inject(SOME_DEFAULT_CONFIG) someDefaultConfig
) {
this.someMergedConfig = Object.assign({}, someDefaultConfig, someConfig);
...
}
}
@NgModule({ providers: [
SomeService,
{ provide: SOME_DEFAULT_CONFIG, useValue { bar: 'bar' } }
] })
export class SomeModule {
static forRoot(config): ModuleWithProviders {
return {
ngModule: SomeModule,
providers: [{ provide: SOME_CONFIG, useValue: config }]
};
}
}
// user-defined module
@NgModule({ imports: [SomeModule.forRoot({ foo: 'foo' })] })
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)
Angular APP_INITIALIZER多提供程序允许为应用程序提供异步初始化例程.
APP_INITIALIZER与AngularJS配置阶段有一些相似之处.APP_INITIALIZER程序很容易受到竞争条件,类似于config和run块AngularJS.例如,由于对另一个Router组件的APP_INITIALIZER循环依赖性,可以在根组件中注入但不能注入APP_INITIALIZER.
AngularJS
...
// user-defined module
angular.module('app', ['some']).config((someServiceProvider) => {
someServiceProvider.configure({ foo: 'foo' });
});
Run Code Online (Sandbox Code Playgroud)
角
...
// user-defined module
export function someAppInitializer(someService: SomeService) {
return () => {
someService.configure({ foo: 'foo' });
};
}
@NgModule({
imports: [SomeModule],
providers: [{
provide: APP_INITIALIZER,
multi: true,
useFactory: someAppInitializer,
deps: [SomeService]
}]
})
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)
初始化可能涉及从远程源获取配置以配置服务; 单个AngularJS应用程序无法实现的功能.这需要另一个初始化和引导主模块的应用程序.这种情况自然会由APP_INITIALIZER.
AngularJS
...
// user-defined module
angular.module('app', ['some']);
angular.module('appInitializer', [])
.factory('initializer', ($document, $http) => {
return $http.get('data.json')
.then((result) => result.data)
.then((data) => {
$document.ready(() => {
angular.bootstrap($document.find('body'), ['app', (someServiceProvider) => {
someServiceProvider.configure(data);
}]);
});
});
});
angular.injector(['ng', 'appInitializer'])
.get('initializer')
.catch((err) => console.error(err));
Run Code Online (Sandbox Code Playgroud)
角
...
// user-defined module
export function someAppInitializer(http: HttpClient, someService: SomeService) {
return () => {
return http.get('data.json').toPromise()
.then(data => {
someService.configure(data);
});
};
}
@NgModule({
imports: [SomeModule],
providers: [{
provide: APP_INITIALIZER,
multi: true,
useFactory: someAppInitializer,
deps: [HttpClient, SomeService]
}]
})
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1581 次 |
| 最近记录: |