Organizing Dependencies with Modules(使用模块来组织依赖关系
In any non-trivial application,figuring out how to organize the functionality of yourcode into areas of responsibility is often a hard task. We’ve seen how controllers give us
a place to put the code that exposes the right data and functions to the view template.But what about the rest of the code we need to support our applications? The mostobvious place to put this would be in functions on the controllers. 笨拙的翻译如下: 在任何正式的应用中,弄清如何组织你代码中的功能逻辑是一项艰巨的任务。之前我们已经见过如何在 controllers 中正确地放置 data 和 functions 到 view templates 中去。但对于我们应用程序中的其他补充代码呢?最明显的地方可能是你 controllers 中的 functions 中。 This works fine for small apps and the examples that we’ve seen so far,but it quicklybecomes unmanageable in real apps. The controllers would become a dumping groundfor everything and anything we need to do. They’d be hard to understand and likely hard to change. 笨拙翻译: 但是这种方法只适用于目前我们见到过的那些小型的应用和例子而已,在真正的应用中,这样做会让程序变得难以控制。这些 controllers 会变成一个啥都放的垃圾场。它们会变得难以改变。 Enter modules. They provide a way to group dependencies for a functional area withinyour application,and a mechanism to automatically resolve dependencies (also knownas dependency injection). Generically,we call these dependencies services,as they providespecific services to our application. 翻译: 进入模块的世界吧。它们为你的应用程序的功能区域提供一个方法来组织依赖关系,它们提供一个机制用于自动地组织应用程序的依赖关系(也即如前所诉的依赖注入)。通常我们把这些叫做 dependencies serives,因为它们为我们的应用程序提供特定的 services。
举个例子,假如我们的 shopping 网站需要从 server 获取一个商品列表,我们会需要一些对象——把它叫做 items——用于从服务器获取这些 items。这个 items 对象,依次地,需要某种方法来连接 server 上的 database 通过 XHR 或 webSockets。假如不用模块的话,我们可以吧代码写成这样: function ItemsViewController($scope) { // make request to server … // parse response into Item objects … // set Items array on $scope so the view can display it ... }While this would certainly work,it has a number of potential problems. ? If some other controller also needs to get Items from the server,we now have toreplicate this code. This makes maintenance a burden,as now if we make schemaor other changes,we have to update that code in several places. 这种做法当然有效,它有大量潜在的问题: 1.假如还有另外一些 controller 需要从服务器获取 items,我们需要重复代码。这就让部署成为一种折磨,此时假如我们对它进行一些改变例如改变协议,我们需要更新代码好几次。 2.比如服务器端验证,我们不得不或者真的有一个 server 在运行,或者 mock 数据。运行服务器会让测试变得缓慢,搭建服务器也是一件很痛苦的事情,而且会让测试变得不可靠,而且让你不得不指定数据的实际格式。而通过 modules 和 dependency injection,我们可以把我们的 controller 写的异常简单,像这样: function ShoppingController($scope,Items) {
$scope.items = Items.query();
} You’re probably now asking yourself,“Sure,that looks cool,but where does Items comefrom?” The preceding code assumes that we’ve defined Items as a service.
Services are singleton (single-instance) objects that carry out the tasks necessary tosupport your application’s functionality. Angular comes with many services like $loca tion,for interacting with the browser’s location,$route,for switching views based onlocation (URL) changes,and $http,for communicating with servers. 很可能你在这样问自己,“好吧,那看起来很酷,但那 items 从哪儿来的呢?”之前的代码已经假设我们把 items 定义成了 service。Services 是单实例的对象 that 分离出应用程序的功能。 Angular 引进了许多像 $location 来处理浏览器 location,$route 来根据 location(URL) 的改变来切换 views,$http 来处理服务器通讯。 You can,and should,create your own services to do all of the tasks unique to yourapplication. Services can be shared across any controllers that need them. As such, You define services with the module object’s API. There are three functions for creatinggeneric services,with different levels of complexity and ability: 1.provider(name,ObjectOR constructor() ) 一个可配置的服务伴随着复杂的创建逻辑。如果传入一个对象,它必须包含一个名为 $get 并返回该服务的实例的的方法。否则,Angular 会假设你传入的是一个构造函数,每当调用这个构造函数,它创建一个实例。 2.factory(name,$getFunction() ) A non-configurable service with complex creation logic. You specify a function that,whencalled,returns the service instance. You could think of this as provider(name,{ $get:$getFunction() } ). 一个不可配置的服务伴随着负责的构造逻辑。你指定一个函数,这个函数每逢调用,它返回服务的实例。你可以把它看成是一个 provider(name,{$get:$getFunction()}) 3.service(name,constructor() ) 一个不可配置的服务伴随着简单的构造逻辑。类似 provider 提供的 contructor 选项,Angular 会调用它来创建一个实例。 We’ll look at the configuration option for provider() later,but let’s discuss an examplewith factory() for our preceding Items example. We can write the service like this: 我们稍后再看 provider() 的配置选项,现在让我们来讨论用 factory() 来实现我们之前的那个 items 的例子。我们可以把 service 写成这样: var home = angular.module("myApp",[]); home.factory("Items",function () { return { query: function () { return [ {name:'The Handsome Heifer',cuisine:'BBQ'},{name:'Greens Green Greens',cuisine:'Salads'},{name:'House of Fine Fish',cuisine:'Seafood'} ]; } }; }); home.controller("DeathrayMenuController",function ($scope,Items) { $scope.directory = Items.query(); $scope.selectRestaurant = function(row) { $scope.selectedRow = row; }; }); When Angular creates the ShoppingController,it will pass in $scope and the newItems service that we’ve just defined. This is done by parameter name matching. That is,Angular looks at the function signature for our ShoppingController class,andnotices that it is asking for an Items object. Since we’ve defined Items as a service,it knows where to get it. 当 Angular 创建 ShoppingController,它会传入 $scope 和刚才创建的这个 Items service。这些工作是由parameter name matching 完成的。 function ShoppingController($scope,Items) {...}也可以写成这个熊样: function ShoppingController(Items,$scope) {...}and it all still functions as we intended. To get this to work with our template,we need to tell the ng-app directive the name ofour module,like the following: 为了让它和我们的 template 合同工作,我们需要把 module 的名称告诉 ng-app,就像这样: <html ng-app='ShoppingModule'>To complete the example,we could implement the rest of the template as: 为了完成这个例子,我们需要把模板搞成这个样子: <body ng-controller="ShoppingController"> <h1>Shop!</h1> <table> <td>{{item.title}}</td> <td>{{item.description}}</td> <td>{{item.price | currency}}</td> </tr> </table> </div>done! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |