Angular 角度:扩展服务和传递参数
我很难理解如何在Angular中扩展服务 我有一个连接到Firebase并执行各种常见任务(获取、设置、更新、列表等)的服务,我没有为我的特殊组件重新编写它,而是尝试扩展它 我的想法是,我可以只通过路径的新部分,但这会抛出一个错误:Angular 角度:扩展服务和传递参数,angular,typescript,Angular,Typescript,我很难理解如何在Angular中扩展服务 我有一个连接到Firebase并执行各种常见任务(获取、设置、更新、列表等)的服务,我没有为我的特殊组件重新编写它,而是尝试扩展它 我的想法是,我可以只通过路径的新部分,但这会抛出一个错误: Cannot resolve all parameters for 'FirebaseService'(?). Make sure that all the parameters are decorated with Inject or have valid typ
Cannot resolve all parameters for 'FirebaseService'(?). Make sure that all the parameters are decorated with Inject or have valid type annotations and that 'FirebaseService' is decorated with Injectable.
问题在于构造函数和我缺乏面向对象的头脑。我可以将其他服务或提供者传递到我的服务中,但我不能再传递简单的字符串参数,除非我遗漏了什么。我尝试设置属性,但我认为我没有正确理解上下文
我想这是@Injectable的问题,但我不确定
以下是我第一次尝试的简化版本:
更新以包含PLUNKER链接:
我希望它能附上“项目”一行。没有,只是重复
然后我试着通过构造函数:
这会把一切都搞砸。我有办法解决这个问题,但这似乎是一个彻底的黑客
将“projects”参数传递给父类的正确方法是什么?更新:如果您想使用标准服务接口而不需要手动实例化,并将简单值传递给构造函数,那么文档建议设置一个工厂,这几乎需要大量的代码: (向下滚动到Factory Providers) 下面的代码工作正常,但未将提供程序系统用于服务:
//things.service.ts
@Injectable()
export class ThingService {
public myString: string = "base";
constructor(str: string) {
this.myString = str;
}
}
@Injectable()
export class Thing2Service extends ThingService {
constructor(){
super('I AM CHILD');
}
}
//app.component.ts
public thingService: ThingService = new ThingService("I AM PARENT");
public thing2Service: Thing2Service = new Thing2Service();
ThingService.myString === "I AM PARENT"; //true
Thing2Service.myString === "I AM CHILD"; //true
因此,在白金汉做了一些出色的工作之后,我决定用“典型”的方式做这件事是不可能的 Angular2简单地用注入器接管构造函数()函数。然而,真正起作用的是生成一个备用的“init”函数,然后您可以将参数传递给它
@Injectable()
export class ParentService {
root:string = "This content comes from: ";
myString:string = "The Parent";
resultString:string;
constructor(){
this.init();
}
init() {
this.resultString = this.root + this.myString;
}
}
@Injectable()
export class ChildService extends ParentService {
constructor(){
super();
}
init() {
this.myString = "The Child";
super.init();
}
}
通过这种方式,您可以在子对象上设置值或将其传递给父对象
这里是另一种扩展angular2服务的方法,它与DI一起工作。子服务不能为父服务使用的可注入服务使用相同的参数名,因此需要另一个HTTP参数名 父服务:
@Injectable()
export class GenericStore {
....
constructor(public config:GenericConfig,private http:Http) {
....
}
....
}
儿童服务:
const DEFAULT_CONFIG:GenericConfig = { ... };
@Injectable()
export class ConfigStore extends GenericStore {
....
constructor(private anotherHttp:Http) {
super(DEFAULT_CONFIG,anotherHttp);
}
....
}
IMO最好的方法是使用抽象属性。这样,扩展类将被强制提供必要的值
abstract class GenericStore{
abstract configVal: string;
constructor(){}
someMethod(){
console.log('The config value is:', this.configVal);
}
}
class UserStore extends GenericStore{
configVal = 'A config value. Typescript will yell if not provided.';
constructor(){
super();
}
}
我认为您对OOP的理解很好,只是angular2在依赖注入方面做了一些聪明但古怪的事情,所以注入/注入需要额外的语法。我将从这里开始:CH,是的,我看到了这一点,将服务注入彼此和组件是完全有意义的。我要做的是在构造函数中传递一个参数,或者从一个子元素传递给一个父元素。在常规的ES6类中,这两种方法似乎都是可能的,但对于Angular DI,它会吃掉它们,我不确定为什么..这段代码适用于常规的Javascript对象,但不适用于Angular 2服务。这是一个具有传递属性的plunker:,这是一个具有您建议的构造函数的plunker。它爆炸了:我正在运行我的答案中查看上面的代码,一模一样。因此,您在编译步骤中遗漏了一些内容,或者出现了一些错误。哦,我明白您的意思。我将服务实例化为类,而不是通过注入器,即使它们已被@Injectable修饰。是的,如果我将它们实例化为类,这很好,但当我尝试使用注入器时,它会抛出错误。如果我只需要没有其他注入器的简单服务,我喜欢你的想法,我认为标准类可以很好地工作,但是如果我尝试向我想要扩展的类中注入一些东西(比如UserService),它会再次抛出错误。很好看@CH Buckingham,我搞砸了你的发现,它确实允许我传递其他信息,但它不允许我简单地“扩展”服务。做这件事需要大量的代码,这有点挫败了扩展的想法。我正在发布一个我发现的答案。。这并不完美,但很有效。嗨,丹尼斯·斯莫莱克,我能问你两个问题吗。1.如果组件类(命名子类)从父类扩展而来,如何将参数传递给子类中的构造函数?2.子组件如何从父组件扩展并传递参数?对于服务:因为注入器处理所有服务的初始化,所以在运行时无法在构造函数中动态传递任何内容,但可以灵活地编写服务代码。例如,我的主服务拥有运行我的Firebase函数的所有代码,然后子服务设置自己的Firebase URL并继承所有父函数。我的子服务覆盖父服务的“init”函数。在我的代码中,这将是“myString”参数。对于组件:它取决于您何时扩展它。如果你想制作一个按钮组件,然后为了一些特殊的功能而扩展它,这很简单,就像我扩展服务的方式一样。如果您想在运行时执行此操作(可能是更简单的想法),您可以在调用组件时设置一些input()值。如果你指的是父/子嵌套组件,那么有很多方法可以传递数据、eventEmitter、父对象,甚至是服务..Dennis你在plunker打印一个异常。mautrok,这个答案非常古老(不管怎么说,对于ng2),所以我肯定有些东西被移动/破坏了。我将看一下rc.5,看看这是否仍然适用,并尝试在某个时候更新plunker。什么是
DEFAULT\u CONFIG
?感谢您的关注。我修好了儿童服务。默认的_配置用于指示数据和管道的源,可以是简单URL或带有事件名称的websocket URL。
@Injectable()
export class GenericStore {
....
constructor(public config:GenericConfig,private http:Http) {
....
}
....
}
const DEFAULT_CONFIG:GenericConfig = { ... };
@Injectable()
export class ConfigStore extends GenericStore {
....
constructor(private anotherHttp:Http) {
super(DEFAULT_CONFIG,anotherHttp);
}
....
}
abstract class GenericStore{
abstract configVal: string;
constructor(){}
someMethod(){
console.log('The config value is:', this.configVal);
}
}
class UserStore extends GenericStore{
configVal = 'A config value. Typescript will yell if not provided.';
constructor(){
super();
}
}