前端开发人员对AngularJS的关注日益增加,市场上有许多框架可供选择,它们大多数都包含了非常常见的特性。EmberJS在AngularJS之前就开始了,并且得到了Apple的支持,ExtJS也是一个功能完备的MVC框架,然后是Backbone.js。但是,AngularJS因其活跃的社区而吸引了大多数人,这个社区在解决问题和扩展其能力方面表现出了巨大的兴趣。随着其在TypeScript方面的最新发展,它吸引了更多的开发者来尝试它。
尽管这个库的许多变化让许多人认为这个库可能没有朝着正确的方向发展,可能会像其他框架一样消失。但到目前为止,Angular仍在发展,保持着对它的兴趣。
根据过去使用AngularJS和.NET背景的经验,发现与其他MVC框架相比,有些东西确实缺失或没有标准化。这并不是说AngularJS没有提供这些特性,而是没有人将这些方面作为框架来关注,而只是因为它被一些顶级博主推荐,所以人们只是尝试使用它。但是,一种尺寸并不能适合所有人。也许想要设置这个框架的方式,其他人甚至不需要它。
本文的目的不是讨论这个框架是什么,或者AngularJS的替代品是什么。相反,将深入探讨框架的一些方面,以克服样板代码,使AngularJS的使用更加甜蜜。
依赖注入是AngularJS最有趣的特性之一。对于具有许多相互关联模块和服务的复杂应用程序的开发来说,它是最有价值的方面。
请阅读官方网站上的Angular实现:。
那么,这个特性工作得很好,这里究竟有什么问题呢?
必须在参数中传递所有依赖项。毫无疑问,这不是最佳实践,也不是可维护的。想象一下,如果需要注入超过5个依赖项,并且需要在每个地方都注入它们。假设已经完成了一半的开发,但是一些设计变更需要更多的依赖项。
官方指南中描述的另一个问题是,在压缩过程中依赖参数名称的变化使得Angular无法找到正确的依赖项。Angular提供了一个解决方案,允许提供$inject
变量或内联参数,以字符串格式指定这些依赖项为数组(v1.5及更早版本),@injectable
和@inject
(v2+)。这很好。但这也增加了上面提到的第一个问题的更多缺点,因为现在必须照顾额外的字符串,它的大小写与构造函数中添加参数的顺序相结合。
Angular并不真正知道需要的依赖项是否已加载。并且它没有提供任何方式从服务器加载它,如果它没有加载。这意味着要么总是必须在构造函数调用之前加载所有依赖项,包括相互关联的依赖项。这在现实世界的复杂应用程序开发中并不实用。
让尝试看看如何解决这些问题。
认为的一个快速解决方案是服务定位器模式。实际上,Angular提供了使用$injector
的服务定位器。很好,这解决了第二个问题。如果只是将该对象作为参数注入,代码看起来会很好。
请参考:。
但如果开发者在每个需要的地方都添加这段代码,那么情况将比试图解决的实际问题更糟。宁愿有一个公共服务或工厂,无论何时需要,都提供依赖项实例。
很好,解决了前两个问题,现在开发者只需要注入服务定位器,这是一个很大的改进。
可以通过使用继承进一步改进这一点。所以基本上,将这些常见的注入部分抽象到父类中,开发者只需要实现这些父类就可以了。当将这种方法与原始实现进行比较时,这是一个巨大的改进。
可以使用相同的BaseService
类来实现其他服务,如上面的代码所示。
还可以调用HTTP()
方法从服务器异步获取数据,只需从上面的GetItems
方法返回一个承诺对象,并由调用者处理。
类似地,将实现BaseController
来使用这个ServiceLocator
:
有两个额外的事情需要注意:
首先,使BaseController
泛型,以实现IScope
类型。这只是为每个继承自这个基类的控制器定义作用域对象。
其次是Init
抽象方法。由于必须预定义构造函数,不希望开发者在子控制器中再次定义它,但仍然需要有一个在创建实例时被调用的方法。
好的,不担心controllerAs
部分,因为实现只是为了说明目的。
最后,控制器将看起来像这样:
就是这样,不是吗?干净且可维护?开发者将更少地关注Angular的维护,而更多地关注功能。
可以以类似的方式实现组件。它需要一些额外的东西来照顾以与AngularJS一起工作。将在下一篇文章中介绍这一点。