如何访问一个角2分量的常数和服务?

我有一个常量文件 常量:

export const C0NST = "constant";

我通过服务 一些服务访问它,如下所示:

import { C0NST } from './constants';


console.log(C0NST); // "constant"

但是,当我在组件模板中访问它时:

Some. Component. ts :

import { C0NST } from './constants';

有些组件.html :

{{ C0NST }} <!-- Outputs nothing -->

然而,在组件类中定义一个成员是可行的:

一些组件

public const constant = C0NST;

有些组件

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

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

112141 次浏览

The scope of Angular2 template bindings is the component instance. Only what's accessible there can be used in bindings.

You can make it available like

class MyComponent {
myConst = CONST;
}
\{\{myConst}}

In Angular2, the template can only access fields and methods of the component class. Everything else is off-limits. This includes things which are visible to the component class.

The way to go around this is to have a field inside the component, which just references the constant, and use that instead.


It's one limitation of the design, but perhaps you should think a bit more about why you need a constant in the template in the first place. Usually these things are used by components themselves, or services, but not the template.

You can create a BaseComponent , it is a place where you should create your constant instances and then you can create your FooComponent extends BaseComponent and you can use your constants.

Since in the Component's template you can only use attributes of the Component's class, you can't directly use any external constants (or external variables).

The most elegant way that I've found so far is the following:

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


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


readonly MY_CONSTANT = MY_CONSTANT;


// ...
}

which basically just creates a new attribute MY_CONSTANT inside the component class. Using readonly we make sure that the new attribute cannot be modified.

Doing so, in your template you can now use:

\{\{ MY_CONSTANT }}

There are two best directions in my opinion:

Wrapping constants as internal component property

enum.ts

export enum stateEnum {
'DOING' = 0,
'DONE',
'FAILED'
}

component.ts

import { stateEnum  } from './enum'
export class EnumUserClass {
readonly stateEnum : typeof stateEnum = stateEnum ;
}

Example uses enum, but this can be any type of defined constant. typeof operator gives you all of benefits of TypeScript typing features. You can use then this variable directly in templates:

component.html

<p>\{\{stateEnum.DOING}}<p>

This solution is less efficient in memory usage context, because you are basically duplicating data (or references to constants) in each component you wish to use it. Beside that, syntax
readonly constData: typeof constData = constData
in my opinion introduce a lot of syntax noise and may be confusing to newcommers

Wrapping external constant in component function

Second option is to wrap your external variable/constant with component function and use that function on template:

enum.ts

export enum stateEnum {
'DOING' = 0,
'DONE',
'FAILED'
}

component.ts

import { stateEnum  } from './enum'
export class EnumUserClass {
getEnumString(idx) {
return stateEnum[stateEnum[idx]];
}
}

component.html

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

Good thing is that data is not duplicated in controller but other major downside occur. According to Angular team, usage of functions in templates is not recommended due to change detection mechanism, which works way less efficient in case of functions returning values to templates: change detection have no idea does value return by a function has changed, so it will be called way often than needed (and assuming you returning const from it, it's actually needed only once, when populating template view. It may be just a bit efficiency killing to your application (if you are lucky) or it may totally break it down if function resolves with Observable for instance, and you use async pipe to subscribe to results. You can refer to my short article on that HERE