是否可以将服务注入子组件?

时间:2019-11-05 11:41:19

标签: angular

我遇到一种情况,我发现自己在父组件中复制逻辑以从服务器获取数据以填充下拉列表(这还包括处理分页和搜索)。因此,我想将此逻辑移到可以一次定义的下拉组件中。

但是,这需要我定义下拉组件应使用哪个服务来获取其数据。我想在父级中定义下拉组件时定义它。

例如

this.service(x,y,z).subscribe()

然后我可以在下拉组件上调用此函数,以传递诸如分页和搜索参数之类的参数。

{{1}}

这可能吗?

我也愿意接受任何其他建议,特别是如果我以错误的方式看待它的话?

2 个答案:

答案 0 :(得分:0)

最好将此笨拙的组件包装到容器中并重复使用。您的智能组件将通过特定界面注入服务。您可以在容器的父组件中声明的服务。

我创建了stack blitz demo

答案 1 :(得分:0)

是的,有可能。您可以执行以下操作(StackBlitz):

1-在接收服务的@Input()中定义一个DropDownComponent属性(在这种情况下,为了更好的设计,我创建了一个接口Logger)。

@Component({
  selector: 'dropdown',
  template: `Dropdown using {{this.logger.getName()}}`
})
export class DropDownComponent implements OnInit {

  @Input() public logger: Logger;

  constructor() { }

  ngOnInit() {
    console.log(`DropDown, I'm using `, this.logger.getName());
  }
}

2-在使用下拉菜单的组件中,然后定义logger属性的值。

@Component({
  selector: 'my-app',
  template: `
  <dropdown [logger]="this.logger1Service" ></dropdown>
  <br />
  <dropdown [logger]="this.logger2Service" ></dropdown>
  `
})
export class AppComponent implements OnInit {

  constructor(
    public logger1Service: Logger1Service,
    public logger2Service: Logger2Service
    ) { }

  ngOnInit() {
    console.log('Hello from AppComponent');
    console.log('calling logger1Service.info() with message X', this.logger1Service.info('X'));
    console.log('calling logger2Service.info() with message Y', this.logger1Service.info('Y'));
  }
}

3-并定义可为此下拉菜单提供的服务。

// logger.interface
export interface Logger {
  info(text: string);
  getName();
}

// logger1.service
import { Injectable} from '@angular/core';

import { Logger } from './logger.interface';

@Injectable({ providedIn: 'root' })
export class Logger1Service implements Logger {

  constructor() { }

  info(text: string) {
    console.log('Logger 1:', text);
  }

  getName() {
    return 'Logger1Service';
  }
}

// logger2.service
import { Injectable} from '@angular/core';

import { Logger } from './logger.interface';

@Injectable({ providedIn: 'root' })
export class Logger2Service implements Logger {

  constructor() { }

  info(text: string) {
    console.log('Logger 2:', text);
  }

  getName() {
    return 'Logger2Service';
  }
}