Angular:常见问题集锦

一、提供商注册到模块中还是组件中?

1.通常,优先把模块中具体特性的提供商注册到模块中(@NgModule.providers),而不是组件中(@Component.providers)。

应该把全应用级提供商添加到根模块AppModule中,而不是还是根组件AppComponent

这是因为惰性加载模块及其组件可以注入AppModule中的服务,却不能注入AppComponent中的。

只有当该服务必须对AppComponent组件树之外的组件不可见时,才应该把服务注册进AppComponentproviders中。 这是一个非常罕见的异常用法。

2.当你必须

把服务实例的范围限制到某个组件及其子组件树时,就把提供商注册到该组件中

 指令的提供商也同样照此处理。


二、不要在共享模块中把应用级单例添加到providers中:

虽然很多组件都共享着同一个服务例,但它们是靠 Angular 的依赖注入体系实现的,而不是模块体系。

比如很多组件都注入了UserService, 在整个应用程序中,只应该有一个UserService的实例,并且它只应该有一个提供商。换句话说,UserService是全应用级单例, 我们不希望每个模块都各自有它的实例。 而如果由SharedModule提供UserService,就会导致铁板钉钉的危险, 否则如果一个惰性加载模块导入了此共享模块,就会导致它自己也生成一份此服务的实例。


三、我要如何知道一个模块或服务是否已经加载过了?

某些模块及其服务只能被根模块AppModule加载一次。 在惰性加载模块中再次导入这个模块会导致错误的行为,这个错误可能非常难于检测和诊断。为了防范这种风险,我们可以写一个构造函数,它会尝试从应用的根注入器中注入该模块或服务。如果这种注入成功了,那就说明这个类是被第二次加载的,我们就可以抛出一个错误,或者采取其它挽救措施。

constructor (@Optional() @SkipSelf() parentModule: CoreModule) {
  if (parentModule) {
    throw new Error(
      'CoreModule is already loaded. Import it in the AppModule only');
  }
}

四、模板引用变量 ( #var )

模板引用变量通常用来引用模板中的某个DOM元素,它还可以引用Angular组件或指令或Web Component,模板引用变量的作用范围是整个模板。不要在同一个模板中多次定义同一个变量名,否则它在运行期间的值是无法确定的。

使用井号 (#) 来声明引用变量(我们也可以用ref-前缀代替#):

#phone的意思就是声明一个名叫phone的变量来引用元素。

我们可以在模板中的任何地方引用模板引用变量,比如在上的phone变量就是在模板另一侧的

大多数情况下,Angular会把模板引用变量的值设置为声明它的那个元素。 在上一个例子中,phone引用的是表示电话号码的框。 "拨号"按钮的点击事件处理器把这个input值传给了组件的callPhone方法。

不过,指令也可以修改这种行为,让这个值引用到别处,比如它自身。 NgForm指令就是这么做的:

{ {submitMessage}}

这里的heroForm实际上是一个Angular NgForm 指令的引用, 因此具备了跟踪表单中的每个控件的值和有效性的能力。

应用实例:

Hero Form

Name is required
Power is required

You submitted the following:

Name
{ { model.name }}
Alter Ego
{ { model.alterEgo }}
Power
{ { model.power }}


五、为什么建议每个文件只放一个类?

在同一个文件中有多个类容易造成混淆,最好避免。 开发人员期望每个文件只放一个类。如果我们蔑视这个建议,并且 —— 比如说 —— 把HeroServiceHeroesComponent组合在同一个文件里, 就得把组件定义放在最后面! 如果把组件定义在了服务的前面, 在运行时抛出空指针错误。

 

你可能感兴趣的:(前端开发,Angular6基础学习)