Angular 如何访问角2组件和服务中的常数?

Angular 如何访问角2组件和服务中的常数?,angular,typescript,Angular,Typescript,我有一个常量文件constants.ts: export const C0NST = "constant"; import { C0NST } from './constants'; {{ C0NST }} <!-- Outputs nothing --> 我在服务some.service.ts中访问它,如下所示: import { C0NST } from './constants'; console.log(C0NST); // "constant" 但是,当我在组件模

我有一个常量文件constants.ts

export const C0NST = "constant";
import { C0NST } from './constants';
{{ C0NST }} <!-- Outputs nothing -->
我在服务some.service.ts中访问它,如下所示:

import { C0NST } from './constants';

console.log(C0NST); // "constant"
但是,当我在组件模板中访问它时:

一些.component.ts

export const C0NST = "constant";
import { C0NST } from './constants';
{{ C0NST }} <!-- Outputs nothing -->
some.component.html

export const C0NST = "constant";
import { C0NST } from './constants';
{{ C0NST }} <!-- Outputs nothing -->
some.component.html

{{ constant }} <!-- constant -->
{{constant}

我不明白为什么我可以直接在服务类中访问导入的常量,但不能在组件模板中访问,即使我在组件类中导入了它。

Angular2模板绑定的范围是组件实例。绑定中只能使用可访问的内容

你可以像这样提供它

class MyComponent {
  myConst = CONST;
}

Angular2模板绑定的范围是组件实例。绑定中只能使用可访问的内容

你可以像这样提供它

class MyComponent {
  myConst = CONST;
}

在Angular2中,模板只能访问组件类的字段和方法。其他一切都禁止进入。这包括组件类可见的内容

解决这个问题的方法是在组件中有一个字段,它只引用常量,然后使用它



这是设计的一个限制,但也许您应该更多地了解为什么首先需要在模板中使用常量。通常这些东西由组件本身或服务使用,而不是模板。

在Angular2中,模板只能访问组件类的字段和方法。其他一切都禁止进入。这包括组件类可见的内容

解决这个问题的方法是在组件中有一个字段,它只引用常量,然后使用它



这是设计的一个限制,但也许您应该更多地了解为什么首先需要在模板中使用常量。通常这些东西由组件本身或服务使用,但不是模板。

您可以创建BaseComponent,在这里您应该创建常量实例,然后您可以创建FooComponent extends BaseComponent并使用常量。

您可以创建BaseComponent,在这里,您应该创建常量实例,然后创建FooComponent extends BaseComponent,并可以使用常量。

由于在组件模板中只能使用组件类的属性,因此不能直接使用任何外部常量(或外部变量)

到目前为止,我发现的最优雅的方式是:

import { MY_CONSTANT } from '../constants';

@Component({
  // ...
})
export class MyTestComponent implements OnInit {

  readonly MY_CONSTANT = MY_CONSTANT;

  // ...
}
这基本上只是在component类中创建了一个新属性
MY_CONSTANT
。我们使用确保不能修改新属性

这样,您现在可以在模板中使用:

{{ MY_CONSTANT }}

由于在组件的模板中只能使用组件类的属性,因此不能直接使用任何外部常量(或外部变量)

到目前为止,我发现的最优雅的方式是:

import { MY_CONSTANT } from '../constants';

@Component({
  // ...
})
export class MyTestComponent implements OnInit {

  readonly MY_CONSTANT = MY_CONSTANT;

  // ...
}
这基本上只是在component类中创建了一个新属性
MY_CONSTANT
。我们使用确保不能修改新属性

这样,您现在可以在模板中使用:

{{ MY_CONSTANT }}

我认为有两个最好的方向:

将常量包装为内部组件属性 enum.ts

public const constant = C0NST;
export enum stateEnum {
  'DOING' = 0,
  'DONE',
  'FAILED'
}
import { stateEnum  } from './enum'
export class EnumUserClass {
  readonly stateEnum : typeof stateEnum = stateEnum ;    
}
export enum stateEnum {
  'DOING' = 0,
  'DONE',
  'FAILED'
}
import { stateEnum  } from './enum'
export class EnumUserClass {
  getEnumString(idx) {
    return stateEnum[stateEnum[idx]];
  }   
}
组件。ts

public const constant = C0NST;
export enum stateEnum {
  'DOING' = 0,
  'DONE',
  'FAILED'
}
import { stateEnum  } from './enum'
export class EnumUserClass {
  readonly stateEnum : typeof stateEnum = stateEnum ;    
}
export enum stateEnum {
  'DOING' = 0,
  'DONE',
  'FAILED'
}
import { stateEnum  } from './enum'
export class EnumUserClass {
  getEnumString(idx) {
    return stateEnum[stateEnum[idx]];
  }   
}
示例使用枚举,但这可以是任何类型的已定义常量
typeof
operator为您提供了TypeScript键入功能的所有好处。然后可以在模板中直接使用此变量:

component.html

<p>{{stateEnum.DOING}}<p>
组件。ts

public const constant = C0NST;
export enum stateEnum {
  'DOING' = 0,
  'DONE',
  'FAILED'
}
import { stateEnum  } from './enum'
export class EnumUserClass {
  readonly stateEnum : typeof stateEnum = stateEnum ;    
}
export enum stateEnum {
  'DOING' = 0,
  'DONE',
  'FAILED'
}
import { stateEnum  } from './enum'
export class EnumUserClass {
  getEnumString(idx) {
    return stateEnum[stateEnum[idx]];
  }   
}
component.html

<p>{{getEnumString(1)}}</p>  
{{getEnumString(1)}}


好的方面是,数据在控制器中并没有重复,但会出现其他主要的缺点。Angular团队表示,由于变更检测机制,不建议在模板中使用函数,这在函数向模板返回值的情况下效率较低:变更检测不知道函数返回的值是否已更改,因此调用该函数的频率将超过需要的频率(假设您从中返回
const
,在填充模板视图时,实际上只需要一次。这可能会降低应用程序的效率(如果您幸运的话)或者,如果函数解析为
可观察的
,并且您使用
异步
管道订阅结果,它可能会完全崩溃。您可以参考我的短文,我认为有两个最佳方向:

将常量包装为内部组件属性 enum.ts

public const constant = C0NST;
export enum stateEnum {
  'DOING' = 0,
  'DONE',
  'FAILED'
}
import { stateEnum  } from './enum'
export class EnumUserClass {
  readonly stateEnum : typeof stateEnum = stateEnum ;    
}
export enum stateEnum {
  'DOING' = 0,
  'DONE',
  'FAILED'
}
import { stateEnum  } from './enum'
export class EnumUserClass {
  getEnumString(idx) {
    return stateEnum[stateEnum[idx]];
  }   
}
组件。ts

public const constant = C0NST;
export enum stateEnum {
  'DOING' = 0,
  'DONE',
  'FAILED'
}
import { stateEnum  } from './enum'
export class EnumUserClass {
  readonly stateEnum : typeof stateEnum = stateEnum ;    
}
export enum stateEnum {
  'DOING' = 0,
  'DONE',
  'FAILED'
}
import { stateEnum  } from './enum'
export class EnumUserClass {
  getEnumString(idx) {
    return stateEnum[stateEnum[idx]];
  }   
}
示例使用枚举,但这可以是任何类型的已定义常量。
typeof
运算符为您提供了TypeScript键入功能的所有好处。您可以直接在模板中使用此变量:

component.html

<p>{{stateEnum.DOING}}<p>
组件。ts

public const constant = C0NST;
export enum stateEnum {
  'DOING' = 0,
  'DONE',
  'FAILED'
}
import { stateEnum  } from './enum'
export class EnumUserClass {
  readonly stateEnum : typeof stateEnum = stateEnum ;    
}
export enum stateEnum {
  'DOING' = 0,
  'DONE',
  'FAILED'
}
import { stateEnum  } from './enum'
export class EnumUserClass {
  getEnumString(idx) {
    return stateEnum[stateEnum[idx]];
  }   
}
component.html

<p>{{getEnumString(1)}}</p>  
{{getEnumString(1)}}

好的方面是控制器中的数据不会重复,但会出现其他主要的缺点。根据Angular团队的说法,不建议在模板中使用函数,因为变更检测机制在函数向模板返回值的情况下效率较低:变更检测不知道函数是否返回值已更改,因此调用它的频率将超过需要的频率(假设您从中返回
const
,在填充模板视图时,实际上只需要一次。这可能会降低应用程序的效率(如果您幸运的话)或者,如果函数解析为
Observable
,并且您使用
async
管道订阅res,它可能会完全崩溃