Reputation: 5101
I have seen an example, and I am trying to reproduce it. The name
and age
are declared inside the class
and services
( Injectable ) added in the constructor
.
I'd like to know the difference between declaring variable with class
and constructor
here. Any one help me to know the differences.
As well instead of declaring the name
and age
can't I declare inside of the constructor
itself?
here is my code :
import {Component} from 'angular2/core';
import {CommonService} from './commonService';
import {commonServiceIndipendent} from './commonSerivceIndipendent';
@Component({
selector : 'component1',
template : `
<h1>Component 1</h1>
<input type="text" #message />
<button (click)="onLog(message.value)" >Component1 - Message </button>
`,
providers:[commonServiceIndipendent]
})
export class Component1 {
name:string; //why here?
age:number; //why here?
//can't i add to constructor? if so how?
constructor (
private _commonService : CommonService,
private _commonServiceIndipendent:commonServiceIndipendent) {}
//sending to same service. it has other instance in history
onLog(message:string) {
this._commonService.log( message );
this.name = "Arif",
this.age = 20;
this.onData();
}
onData() {
this._commonServiceIndipendent.myData(this.name,this.age);
}
}
Upvotes: 18
Views: 42980
Reputation: 34915
As the variables are defined, they are members of the Component1
class and any instance of the Component1
class has a name
and an age
public members of respectively string
and number
types.
After the TypeScript is transpiled, there is no difference whether you declare them in the constructor
, or as members. Before it's transpiled however, you have access to these members from instances of this class. This allows you to see errors while you're developing, like for example trying to set the age
of a Component1
to something different from a number
.
var x = new Component1(a, b);
x.age = "a"; // IDE/editor shows you have a problem here.
The difference comes when you define a class member to be private. Then there is difference after the transpilation.
Here's some docs on TS classes.
Upvotes: 2
Reputation: 21756
in this case
export class Component1 {
constructor (
private _commonService : CommonService,
private _commonServiceIndipendent:commonServiceIndipendent) {
}
is similar to this
export class Component1 {
private _commonService : CommonService;
private _commonServiceIndipendent:commonServiceIndipendent;
constructor (
_commonService : CommonService,
_commonServiceIndipendent:commonServiceIndipendent) {
this._commonService = _commonService;
this._commonServiceIndipendent = _commonServiceIndipendent;
}
if you do not use in the constructor protected
, private
, or public
, for example, DI, the range of the variable _commonService
is the scope of the constructor { }
you could not use from another function.
for example:
export class Component1 {
constructor (
_commonService : CommonService,
_commonServiceIndipendent:commonServiceIndipendent) {
_commonService .... Work
}
foo(){
_commonService ..... Cannot find name '_commonService'.
this._commonService ..... Property '_commonService' does not exist on type 'yourClass'.
}
If you not assign it to another variable that has the scope of the class,so you no could refer to this variable, with this
keyword.
export class Component1 {
name:string; //why here?
age:number; //why here?
//can't i add to constructor? if so how?
in typescript without Angular2, you can do this with nothing more:
constructor (name:string, age:number) {}
but in typescript with Angular2, Angular2 is responsible, most of the time, to make use of DI for exaple here:
constructor (private _commonServiceIndipendent:commonServiceIndipendent){}
you use for that providers:[commonServiceIndipendent]
.
Angular2: Inject a non @Injectable class
How to use Dependency Injection (DI) correctly in Angular2?
Upvotes: 11
Reputation: 658263
If you delcare a field outside of the constructor it's available for tools that do static analysis, like a linter or autocompletion.
If you add fields in the constructor, such tools would need to analyze the code flow (there could be if
, for
, ...) in the constructor and it could depend on constructor parameters if fields are actually created or not. This makes it quite difficult and is usually not supported.
Declaring the fields outside the constructor is for a more static approach like in compiled languages. Creating them in the constructor is a dynamic approach usually not available in compiled languages.
If it's only for initializing the fields with literal values it's also more concise. You often might not even need a constructor at all.
class MyClass {
startValue:number = 1;
}
There is also another way using a constructor
class MyClass {
constructor(private someField:string) {}
}
which also creates a private
field (could also be public
). This way also makes the field known for static analysis, because the field is created unconditionally (not dependent on values only known at runtime)
Upvotes: 4