2017-02-22 113 views
8

我有一个声明MetricsService服务的组件。该服务需要http模块和两个字符串,这两个字符串定义主机和授权密钥才能使用。如何编写需要角2中参数的服务构造函数?

度量的服务如下:

@Injectable() 
export class MetricsService { 
    constructor(
     private http: Http, 
     public wsAuthKey: string, 
     public wsHost: string 
     ) { 
     this.wsAuthKey = wsAuthKey || "blahblahblahblahblahblahblahblah="; 
     this.wsHost  = wsHost || "https://preprod-admin.myservice.ws"; 
    } 

使用它是如下编写的组件:

export class DatavizComponent implements OnInit, OnChanges { 
    constructor(
     private zms: MetricsService, 
    ) { 
    } 

我的问题是我应该怎么写的组件构造,使整个事情作品,包括传递主机和密钥(但不传递http)?

注意:目前编写的代码不能编译。

更确切地说,我希望该组件提供取决于应用的数据是这样的:

export class DatavizComponent implements OnInit, OnChanges { 
     constructor(
      private zms = MetricsService("http://myhost.com", "mykey"), 
     ) { 
     } 

但是,如果这个工程,如何通过HTTP?

更新后提出的解决方案:

export class MetricsService { 

    constructor(
     private http: Http, 
     @Inject('wsAuthKey') @Optional() public wsAuthKey?: string, 
     @Inject('wsHost') @Optional() public wsHost?: string 
     ) { 
     this.wsAuthKey = wsAuthKey || "blahblah="; 
     this.wsHost  = wsHost || "https://preprod-admin.host.ws"; 


     console.log("MetricsService constructor=" 
      + " wsAuthKey="+this.wsAuthKey 
      + ", wsHost="+this.wsHost 
     ); 

    } 

在组件:

@Component({ 
    selector: 'dataviz-offers-volumes', 
    templateUrl: 'app/dataviz.component.html', 
    styleUrls: ['app/dataviz.component.css'], 
    encapsulation: ViewEncapsulation.None, 
    providers: [ 
     {provide: 'wsAuthKey', useValue: 'abc'}, 
     {provide: 'wsHost',  useValue: 'efg'}, 
    ], 
}) 
export class DatavizComponent implements OnInit, OnChanges { 

    @ViewChild('chart') private chartContainer: ElementRef; 
    @Input() private graphId:string; 
    @Input() private wsAuthKey:string; 
    @Input() private wsHost:string; 
    @Input() private maxSamples=12; 

    constructor(
     private zms: MetricsService 
    ) { 
    } 

在构造函数中,日志如下(值不会传递):

MetricsService constructor= wsAuthKey=blahblah=, wsHost=https://preprod-admin.host.ws 

它应该显示'abc'和'efg'。

但我想知道是否没有使用dataviz组件的组件的问题。 在此组件中,下面的信息已通过了:

@Input() private wsAuthKey:string; 
@Input() private wsHost:string; 

正如我想的标记任选地预设的宿主和键:

   <h1>dataviz volume</h1> 
       <div class="chartContainer left" title="Simultaneous offers via dataviz directive"> 
        <dataviz-offers-volumes 
         id="dataviz-volumes1" 
         [graphId]="graphId" 
         [wsAuthKey]="'myauthkey'" 
         [wsHost]="'http://myhost.com'" 
         [maxSamples]="123" 
        > 
        </dataviz-offers-volumes> 
       </div> 
+0

你究竟在哪里打算通过这些wsAuthKey和wsHost?它们是特定于应用程序还是特定组件?它看起来并不像你想在你的例子中传递任何东西,所以目前还不清楚它应该如何工作。 – estus

+0

这些数据是特定于使用组件的应用程序的(虽然该服务提供了默认值)。我期待从组件内提供它们? (我在问题中添加了一小段)@estus –

+0

当然,它们在构造函数中是未定义的。它们是绑定的,不适用于施工。而且,我认为没有理由让它们成为绑定(Input),它们没有改变。这完全取决于如何使用这些值。是否有真正的理由为什么这些值应该通过attrs传递,或者如果您需要它,您正试图提供此功能?这将使整个事情变得更加复杂。您需要提供有关MetricsService如何工作的详细信息 - 例如,它可能不是单身人士。 – estus

回答

7

这是在this question描述的共同配方尤其是。这应该是保存配置的服务:

​​

在这种情况下,当需要改变时,它可以被覆盖或扩展为整个模块或特定组件:

@Component(
    ... 
    { provide: MetricsConfig, useClass: class ExtendedMetricsConfig { ... } } 
) 
export class DatavizComponent ... 

有没有真正的在这种情况下需要使MetricsConfig成为一类。它也可以是一个OpaqueToken值提供者。但是一个类可以方便地扩展,它更容易注入并且已经提供了一个输入界面。

+0

这是确定的方法 - – chrismarx

14

你可以说,不支持作为提供商键加入了对原始值@Optional()(DI)和?(打字稿),并@Inject(somekey)可选参数

@Injectable() 
export class MetricsService { 
    constructor(
     private http: Http, 
     @Inject('wsAuthKey') @Optional() public wsAuthKey?: string, 
     @Inject('wsHost') @Optional() public wsHost?: string 
     ) { 
     this.wsAuthKey = wsAuthKey || "blahblahblahblahblahblahblahblah="; 
     this.wsHost  = wsHost || "https://preprod-admin.myservice.ws"; 
    } 
providers: [ 
    {provide: 'wsAuthKey', useValue: 'abc'}, 
    {provide: 'wsHost', useValue: 'efg'}, 
] 

如果他们它们通过,否则它们被忽略,但DI仍然可以注入MetricsService

+0

到目前为止,除了提供者部分外,这很好:我把它放在使用服务的组件中,对吗? –

+0

如果服务本身也在组件中提供,则可以将提供程序放入组件中。这些值需要提供与服务或更高级别相同的级别。 'AppModule'提供的服务无法从'MyComponent'注入值。 –

+0

因为我这样做了,并且组件提供的useValue中的值没有传递给服务。我更新我的问题,以便您可以看到我现在的位置@AngularFrance –

相关问题