简体   繁体   English

为什么我们需要通过angular2中的构造函数注入服务?

[英]Why we need to inject service through constructor in angular2?

I'm learning Angular 2. And got confused over constructor. 我正在学习Angular2。对构造函数感到困惑。 Consider the below code : 考虑下面的代码:

import { Component, OnInit } from '@angular/core';
import { FormGroup,FormsModule,FormControl } from '@angular/forms';
import { WeatherService } from '../weather.service';
import { WeatherItem } from '../weather-item';

@Component({
  selector: 'app-weather-search',
  templateUrl: './weather-search.component.html',
  styleUrls: ['../../assets/app.css'],
  //providers: [WeatherService]
})
export class WeatherSearchComponent implements OnInit {

 constructor(private _weatherService : WeatherService) { }

  onSubmit(form : FormGroup){
    //alert(form.value.location);
    this._weatherService.searchWeatherData(form.value.location)
    .subscribe(
        data => {
            const weatherItem = new WeatherItem(data.data.request["0"].query,data.data.weather["0"].maxtempC,data.data.weather["0"].maxtempC);
            this._weatherService.addWeatherItems(weatherItem);
            console.log(form);
        })

  } 

  ngOnInit() {
  }

}

Here we are injecting 'WeatherService' in constructor. 在这里,我们在构造函数中注入“ WeatherService”。 Can't we do the same outside constructor ? 我们不能做同样的外部构造函数吗? What constructor is doing here actually? 构造函数实际上在这里做什么? Do we really need it here? 我们真的需要吗?

The constructor itself is not doing actual work. 构造函数本身并没有做实际的工作。
Angular creates a new WeatherSearchComponent executing Angular创建一个新的WeatherSearchComponent执行

new WeatherSearchComponent(weatherService);

and this causes the constructor in WeatherSearchComponent to receive the weatherService value. 这会导致WeatherSearchComponent的构造函数接收weatherService值。

The constructor 构造函数

constructor(private _weatherService : WeatherService)

causes an instance field _weatherService to be created and initialized with the value passed from DI. 导致实例字段_weatherService被创建并使用从DI传递的值进行初始化。

The constructor is the only place where it is easy to know when the injected service is available and when not. 构造函数是唯一容易知道何时可以使用注入服务以及何时不可用的地方。

If the service would passed to a field, setter or method, code in the constructor could not access it because the constructor is executed before outside code has a change to set a field or call a method. 如果服务将传递给字段,设置器或方法,则构造函数中的代码将无法访问它,因为构造函数是在外部代码更改设置字段或调用方法之前执行的。

Also for code outside the constructor it is not safe to assume the service is available because this code could be called from the constructor before a field could be set from the outside. 同样对于构造函数外部的代码,也不安全地假定服务可用,因为可以在从外部设置字段之前从构造函数调用此代码。

For dependency injection passing dependencies to the constructor is the only way to avoid a lot of complexity. 对于依赖项注入,将依赖项传递给构造函数是避免大量复杂性的唯一方法。

Dependency Injection in constructor is always better option and while the component is getting created it will get the weatherService as a parameter. 构造函数中的依赖注入始终是更好的选择,并且在创建组件时,它将把weatherService作为参数。 To make it clear, below is the transpiled code for your snippet. 为了清楚起见,下面是您的代码段的转译代码。

var WeatherSearchComponent = (function () {
        function WeatherSearchComponent(_weatherService) {
            this._weatherService = _weatherService;
        }
        WeatherSearchComponent.prototype.onSubmit = function (form) {
            var _this = this;
            //alert(form.value.location);
            this._weatherService.searchWeatherData(form.value.location)
                .subscribe(function (data) {
                var weatherItem = new weather_item_1.WeatherItem(data.data.request["0"].query, data.data.weather["0"].maxtempC, data.data.weather["0"].maxtempC);
                _this._weatherService.addWeatherItems(weatherItem);
                console.log(form);
            });
        };
        WeatherSearchComponent.prototype.ngOnInit = function () {
        };
        WeatherSearchComponent = __decorate([
            core_1.Component({
                selector: 'app-weather-search',
                templateUrl: './weather-search.component.html',
                styleUrls: ['../../assets/app.css'],
            })
        ], WeatherSearchComponent);
        return WeatherSearchComponent;
    }());
    exports.WeatherSearchComponent = WeatherSearchComponent;

As you can see in turn the javascript code has weatherService Instance being passed on to the function weatherSearchComponent. 如您所见,JavaScript代码将weatherService实例传递给了weatherSearchComponent函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM