AngularJS 的角度 - 第一部分






4.23/5 (5投票s)
使用 TypeScript 扩展 AngularJS,
第一部分 - 使用 TypeScript 扩展 AngularJS
最近,AngularJS 引起了前端开发人员的广泛关注。有许多框架可供选择,其中大多数都具备非常普遍的功能。EmberJS 早于 AngularJS 问世,并得到了苹果的支持,ExtJS 也是一个功能齐全的 MVC 框架,还有 Backbone.js。促使我们大多数人选择 AngularJS 的是其活跃的社区,能够解决各种问题,并且科技界对其扩展能力有着极大的兴趣。现在,随着 TypeScript 的最新发展,它吸引了更多开发人员前来尝试。
这个库已经发生了许多变化,让许多人认为这个库的方向不对,可能会像其他框架一样消失。但就目前而言,Angular 仍在不断发展,并保持着我们的兴趣。
根据我过去使用 AngularJS 的经验以及 .NET 的背景,我发现与其他 MVC 框架相比,有些东西确实缺失或不标准化。并不是说 AngularJS 完全不提供这些功能,而是问题在于没有人将这些方面作为一个框架来关注,而是仅仅因为一些顶级博主这么说就按原样使用。好吧,一刀切的做法是行不通的。也许我设置这个框架的方式,其他人根本不需要。
本文无意讨论这个框架是什么,或者 angularjs 的替代方案是什么。相反,我们将深入探讨框架的某些方面,以克服样板代码,让 AngularJS 更加好用。
@inject
, @injectable
, $inject
, $injector
… 是什么?
依赖注入一直是 AngularJS 最有趣的功能。对于拥有大量相互关联模块和服务的复杂应用程序来说,它是最有价值的开发方面。
请阅读官方网站上关于 Angular 依赖注入的实现:https://docs.angularjs.org/guide/di。
参考:https://docs.angularjs.org/guide/di
所以这件事效果很好,这里到底有什么问题?
- 你必须在参数中传递所有依赖项。这无疑不是一个最佳实践,也无法维护。想象一下,如果你需要在到处注入超过 5 个依赖项。然后,假设你已经开发到一半,而某些设计更改需要更多依赖项。
- 官方指南中描述的另一个问题是,在压缩过程中依赖项参数名称会发生变化,这使得 Angular 无法找到正确的依赖项。Angular 提供了解决方法,允许通过提供
$inject
变量或内联参数来以string
格式(v1.5 及更早版本)、@injectable
和@inject
(v2+)的形式将这些依赖项作为数组指定。这很好。但这也增加了我上面提到的第一个问题的缺点,因为现在你必须同时处理额外的string
、其大小写、构造函数中的参数以及最重要的是它们的顺序。 - Angular 并不真正知道你需要的依赖项是否已加载。并且不提供任何方法从服务器加载它(如果未加载)。这意味着你必须在调用构造函数之前始终加载所有依赖项,包括相互关联的依赖项。在现实世界复杂的应用程序开发中,这并不实用。
让我们看看如何解决这些问题。
我想到的一个快速解决方案是服务定位器模式。事实上,Angular 通过 $injector
提供了服务定位器。太好了,这解决了我们的第二个问题。如果我们只是将该对象作为参数注入,我们的代码就会看起来不错。
参考:https://docs.angularjs.org/api/auto/service/$injector
但是,如果开发人员在他们需要的任何地方都添加此代码,那么情况会比我们试图解决的实际问题更糟。我宁愿有一个通用的服务或工厂,在我需要时提供依赖项实例。
太好了,我们解决了前两个问题,现在开发人员只需要注入服务定位器,这是一个很大的改进。
我们还可以通过使用继承来进一步改进这一点。所以基本上,我们将这些通用的注入部分抽象到父类中,开发人员只需要实现这些父类即可。与我们原始的实现相比,这种方法有了巨大的改进。
我可以使用相同的 BaseService
类来实现我上面代码中所示的其他服务。
我也可以调用 HTTP()方法从服务器异步获取数据,只需从上面的 GetItems
方法返回 Promise 对象,并在调用者处处理。
同样,我们将实现 BaseController
来使用这个 ServiceLocator
还有两点需要注意
首先,我将 BaseController
设置为通用的,以实现 IScope
类型。这只是为了定义继承自该基类的每个控制器的作用域对象。
其次是 Init 抽象
方法。由于我们必须预定义构造函数,因此我们不希望开发人员在子控制器中再次定义它,但我们仍然需要一个在创建实例时被调用的方法。
好吧,我不在乎 controllerAs
部分,因为我的实现只是为了说明目的。
最后,我们的控制器看起来会像这样
就这样,难道不干净且易于维护吗?开发人员将减少关注 Angular 的维护,而更多地关注功能。
我们可以以类似的方式实现组件。这需要一些额外的考虑才能与 AngularJS 一起工作。我将在下一篇文章中介绍。
我一开始提到的另一个问题是动态加载服务,我们还没有真正解决。我将在我的下一篇文章中展示这一点,并附带完整的源代码。
希望它能给你一些想法,并激励开发人员将 AngularJS 用作框架,而不仅仅是一个库。