我@Injectable在bootstrap中定义了一个服务.我想在不使用构造函数注入的情况下获取服务的实例.我试过使用ReflectiveInjector.resolveAndCreate但似乎创建了一个新实例.
我试图做的原因是我有一个由许多组件派生的基本组件.现在我需要访问服务,但我不想将它添加到ctor,因为我不想在所有衍生组件上注入服务.
TLDR:我需要一个 ServiceLocator.GetInstance<T>()
更新: RC5 +的更新代码:存储用于组件的进样器实例
我试图将http提供程序导入服务,但是我收到以下错误:
无法解析'AppService'(?)的所有参数.确保所有参数都使用Inject进行修饰或具有有效的类型注释,并且"AppService"使用Injectable进行修饰.
以下是一些代码段:
<script src="~/es6-shim/es6-shim.min.js"></script>
<script src="~/systemjs/dist/system-polyfills.js"></script>
<script src="~/angular2/bundles/angular2-polyfills.js"></script>
<script src="~/systemjs/dist/system.src.js"></script>
<script src="~/rxjs/bundles/Rx.js"></script>
<script src="~/angular2/bundles/angular2.dev.js"></script>
<script src="~/angular2/bundles/http.dev.js"></script>
<!-- 2. Configure SystemJS -->
<script>
System.config({
map: { 'rxjs': 'RCO/rxjs' },
packages: {
RCO: {
format: 'register',
defaultExtension: 'js'
},
'rxjs': {defaultExtension: 'js'}
}
});
System.import('RCO/Areas/ViewOrganization/AngularTemplates/boot')
.then(null, console.error.bind(console));
Run Code Online (Sandbox Code Playgroud)
boot.ts
import {bootstrap} from 'angular2/platform/browser'
import {HTTP_PROVIDERS} from 'angular2/http'
import 'rxjs/add/operator/map'
import {AppComponent} from 'RCO/Areas/ViewOrganization/AngularTemplates/app.component'
import {AppService} from 'RCO/Areas/ViewOrganization/AngularTemplates/app.service'
bootstrap(AppComponent, [HTTP_PROVIDERS, AppService]);
Run Code Online (Sandbox Code Playgroud)
app.service.ts
import {Injectable} from 'angular2/core';
import {Http, Response} from 'angular2/http';
import {Observable} …Run Code Online (Sandbox Code Playgroud) typescript systemjs angular2-services angular2-injection angular
我创建了一个ApiService类来处理我们的自定义API查询,同时使用我们自己的序列化程序+其他功能.
ApiService的构造函数签名是:
constructor(metaManager: MetaManager, connector: ApiConnectorService, eventDispatcher: EventDispatcher);
Run Code Online (Sandbox Code Playgroud)
MetaManager 是一种处理api的metadatas的可注射服务.ApiConnectorService是一个包装的服务,Http用于添加我们的自定义标题和签名系统.EventDispatcher 基本上是Symfony的事件调度系统,在打字稿中.当我测试时ApiService,我做了一个初始化beforeEach:
beforeEach(async(() => {
TestBed.configureTestingModule({
imports : [
HttpModule
],
providers: [
ApiConnectorService,
ApiService,
MetaManager,
EventDispatcher,
OFF_LOGGER_PROVIDERS
]
});
}));
Run Code Online (Sandbox Code Playgroud)
它工作正常.
然后,添加我的第二个规范文件,该文件是ApiConnectorService,与此beforeEach:
beforeEach(async(() => {
TestBed.configureTestingModule({
imports : [HttpModule],
providers: [
ApiConnectorService,
OFF_LOGGER_PROVIDERS,
AuthenticationManager,
EventDispatcher
]
});
}));
Run Code Online (Sandbox Code Playgroud)
并且所有测试都因此错误而失败:
错误:无法解析ApiService的所有参数:(MetaManager,?,EventDispatcher).
api-connector-service.spec.ts(ApiConnectorService的spec文件),ApiService测试将成功.api-service.spec.ts(ApiService …karma-jasmine angular2-services angular2-injection angular2-testing angular
我想创建服务,它可以与一个组件进行交互.我的应用程序中的所有其他组件应该能够调用此服务,并且此服务应该与此组件交互.
如何从服务中调用组件方法?
@Component({
selector:'component'
})
export class Component{
function2(){
// How call it?
}
}
Run Code Online (Sandbox Code Playgroud)
从这个服务?
@Injectable()
export class Service {
callComponentsMethod() {
//From this place?;
}
}
Run Code Online (Sandbox Code Playgroud) typescript angular2-services angular2-injection angular2-components angular
我一直在研究Angular 2 API ComponentResolver以及DynamicComponentResolver创建动态组件,但我有一些不同于那些API提供的东西.
在NG2中是否有任何方法可以基于其类名字符串创建组件?
例如,我正在构建一个可配置的图表仪表板.每个用户的布局都存储在数据库中,说明他们需要2x折线图,3x条形图等.
当我将这些数据加载为json时,它看起来像:
user.charts = [
{ type: 'LineChartComponent', position: ... }
{ type: 'BarChartComponent', position: ... }
];
Run Code Online (Sandbox Code Playgroud)
type我想要反射创建的组件的类名在哪里.
到目前为止,我有以下内容:
this.chartMap = {
'LineChartComponent': LineChartComponent
};
let config = this.configuration;
let chartComponentType = this.chartMap[config.type];
let factory = this.componentFactory.resolveComponentFactory(chartComponentType);
let component = factory.create(this.injector);
component.instance.configuration = config;
this.chartContainer.insert(component.hostView);
Run Code Online (Sandbox Code Playgroud)
但整个想法是消除对的需要chartMap.如何在不引用类型的情况下基于字符串反射性地创建此类?
是否有有关模块生命周期的信息。目前 Angular 内部组件的生命周期有很好的文档记录,我们有诸如 、 等钩子ngOnInit()方法ngDoCheck()。
我们是否有类似的 Angular 模块生命周期钩子?我在哪里可以读到这方面的内容?
我想要完成的是每个应用程序初始化只调用一次外部 API。
我有一个简单的服务,
@Injectable()
export class XService {
url = "http://api.example.com"
constructor(private _http:Http) {
}
callAnAPI(){
console.log('made an external request");
return this._http.get(url)
.map(res=>res.json());
}
}
Run Code Online (Sandbox Code Playgroud)
和两个组件,主要 appComponent
@Component({
selector: 'my-app',
template: `
<div>
Test
</div>
`
})
export class AppComponent {
isLoading = true;
results = [];
constructor(private _service: XService){
}
ngOnInit(){
Observable.forkJoin(
this._service.callAnAPI()
// some more services here
)
.subscribe(
res => {
this.results = res[0];
},
null,
() => {this.isLoading = false}
);
}
}
Run Code Online (Sandbox Code Playgroud)
和另一个与路由一起使用的组件
@Component({
template: …Run Code Online (Sandbox Code Playgroud) 我有一个方法handleError(),如文档https://angular.io/docs/ts/latest/guide/server-communication.html#!#error-handling
private handleError(error: any) {
console.error(error);
console.log(this.loginService); // <- always undefined
return Observable.throw(error);
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,this.loginService是未定义的,尽管它已在我的类中正确注入.它已经在其他方法中使用,但似乎在handleError中不可用.
http-catch调用方法的方式可能是问题吗?如果是这样,我怎么能绕过那个?处理错误时我需要执行一些逻辑.
这是一个关于如何将handleError方法设置为回调的示例(与文档完全一样)
this.http.get(url,
ApiRequest.ACCEPT_JSON)
.map(ApiHelper.extractData)
.catch(this.handleError);
Run Code Online (Sandbox Code Playgroud) 我的应用程序中的一项服务存在问题。问题是,无论在何处注入此服务,我都会收到以下错误:
Uncaught (in promise): Error: Can't resolve all parameters for TestComponent: ([object Object], ?, [object Object])
Run Code Online (Sandbox Code Playgroud)
我知道这个问题可能是由于使用桶引起的,但是我没有将桶用于服务,而是“直接”引用文件,例如:../../core/services/config.service。
正如这个答案@Inject(forwardRef(...))中所建议的,我尝试在注入该服务的任何地方使用。我唯一的例外是AppComponent在这种情况下我“正常”注入相同的服务并且没有收到错误:
export class AppComponent implements OnInit {
constructor(
private configService: ConfigService, // NO ERROR
private router: Router
) { }
...
}
Run Code Online (Sandbox Code Playgroud)
在所有其他地方,如果我不执行以下操作,我会收到上述错误:
export class BuyButtonComponent {
constructor(
@Inject(forwardRef(() => ConfigService)) private configService: ConfigService,
// private configService: ConfigService // DOES NOT WORK
) { }
...
}
Run Code Online (Sandbox Code Playgroud)
据我了解,forwardRef()当要注入依赖项但尚未定义时使用。是ConfigService从CoreModule中导入的提供的AppModule。这些组件位于我拥有的a …
我在Angular2(2.0.0-beta.0)应用程序中定义了一个服务.它是这样的:
import {Injectable} from "angular2/core";
@Injectable()
export class MyService {
constructor() {
}
getSomething() {
return 'something';
}
}
Run Code Online (Sandbox Code Playgroud)
我把它放在我的主应用程序文件中的bootstrap()函数中,以便它通常可用于我的代码:
bootstrap(App, [MyService, SomeOtherService, ROUTER_DIRECTIVES[);
Run Code Online (Sandbox Code Playgroud)
有时我不能在组件中使用该服务,即使我myService:MyService在组件constructor()函数中有类似的东西,如下所示:
import {MyService} from '../services/my.service';
@Component({
selector: 'my-component',
directives: [],
providers: [],
pipes: [],
template: `
<div><button (click)="doStuff()">Click Me!</button></div>
`
})
export MyComponent {
constructor(myService:MyService) {} // note the private keyword
doStuff() {
return this.myService.getSomething();
}
}
Run Code Online (Sandbox Code Playgroud)
在其他地方它工作正常.在它不起作用的地方,我收到一条消息,如果我尝试访问它:
EXCEPTION: TypeError: Cannot read property 'getSomething' of undefined
Run Code Online (Sandbox Code Playgroud)
它基本上意味着服务没有注入.
是什么导致它不被注射?