`

AngularJS开发中,何时应该使用Directive、Controller、Service

阅读更多

AngularJS是一款非常强大的前端MVC框架。同时,它也引入了相当多的概念,有:

        a.Directive(指令)
        b.Controller(控制器)
        c.Service (服务)

        下面我们逐个来看这些概念,研究一下为什么它们会像当初设计的那样强大,同时研究一下为什么我们要以那样的方式去使用它们。我们从Service开始。

一.SERVICES(服务)
        如果你已经使用过AngularJS,你可能已经遇到过Service这个概念了,简而言之,Service就是【单例对象】在AngluarJS 中的一个别名。这些小东西(指单例对象)会被经常传来传去,保证你每次访问到的都是同一个实例,这一点和工厂模式不同。基于这种思想,单例对象让我们可以 实现一些相当酷的功能,它可以让很多controller和directive访问内部的数值。在#angularjs 频道(译者注:指的是原作者自己的博客频道)里面这也是非常常见的问题之一,那就是在应用中的不同代码块之间如何共享数据?我们来看这个问题。

        我们首先来创建一个module(模块),本文中的所有代码都会用到这个module。

var serviceModule = angular.module("bookServices", []);

        下一步,我们来创建一个新的service(服务)。假设我们上面的这个module是用来管理图书的。所以,这里我们来创建一个Book service,然后把一个JSON对象数组添加到这个serice中,这些对象代表很多book数据。

serviceModule.service('Book', ['$rootScope', function($rootScope) {
	var service = {
		books : [{title : "Magician", author : "Raymond E. Feist"}, 
		          {title : "The Hobbit", author : "J.R.R Tolkien"}],
		addBook : function(book) {
			service.books.push(book);
			$rootScope.$broadcast('books.update');
		}
	};
	return service;
}]);

        这是一个非常简单的service(有时候这样就够你用了)。我们这里正在做的事情就是在管理一个book 数组,同时还带有一个addBook方法,在有需要的时候可以添加更多书籍。addBook方法还会在application上广播一个事件,告诉所有正在使用我们的service的人,数组已经被更新了,从而让它们自己也做一些刷新操作。现在,我们要做的就是把这个service传递给各种controller、directive、filter,或者其它任何需要它的东西---然后它们就可以访问service中的这些方法和属性了。好,我们来动手。

var ctrl = [ '$scope', 'Book', function( scope, Book ) {
	   scope.$on( 'books.update', function( event ) {
	     scope.books = Book.books;
	     scope.$apply();//注意,原文这里少了这一行
	   }); 
	   scope.books = Book.books;
}];

controllerModule.controller( "books.list", ctrl );

        同样非常简单。我们上面所做的就是为我们的module创建了一个新的controller。在创建的时候把$scope provdier和我们自己的Book service传递给了它。能明白我们在干嘛吗?我们把前面创建的Book service中的books数组赋给了controller内部的局部scope对象。很酷,对吧?

        好,这里的核心问题是什么呢?我们节省了一些时间,并且在controller上创建了一个数组。对---我们确实这样做了。这样做确实也为我们节约了一点时间---但是如果我们要在其它地方处理这些书籍信息应该怎么办呢?通过scope来维护数据是非常粗暴的一种方式。由于其它controller、directive、model的影响,scope很容易就会崩溃或者变脏。它很快就会变成一团乱麻。通过一种集中的途径(在这里 就是service)来管理所有书籍数据,然后通过某种方式来请求修改它,这样不仅仅会更加清晰---同时当应用的体积不断增大的时候也更加容易管理。最后,它还可以让你的代码保持模块化(这也是Angular很擅长的一件事情)。一旦你在其它项目中需要用到这个service,你没有必要在scope、controller、filter等等东西里面到处去查找相关的代码,因为所有东西都在service里面!

        好。那么我们什么时候应该使用service呢?答案是:无论何时,当我们需要在不同的域中共享数据的时候。另外,多亏了Angular的依赖注入系统,实现这一点是很容易并且很清晰的。

 

二.CONTROLLERS(控制器)

        我们再来看控制器!除非你曾经使用过前端MVC,否则从服务端MVC的思维模式转向客户端MVC的思维模式就如同一次脑筋急转弯。为什么会这样呢? 这是因为,虽然在前端开发中controller实现了非常类似的功能,但是它同时还会实现一些与服务端controller非常不同的功能。在 Angular中,controller自身并不会处理"request",除非它是用来处理路由(route)的(很多人把这种方式叫做创建route controller---路由控制器),更明确地说,尤其是你的应用里面那些作为界面的一部分的controller,它们只会管理非常小的一段代码。

        controller应该纯粹地用来把service、依赖关系、以及其它对象串联到一起,然后通过scope把它们关联到view上。如果在你的 视图里面需要处理复杂的业务逻辑,那么把它们放到controller里面也是一个非常不错的选择。回到我们前面的这个books例子,我实际上并没有什么东西需要添加到controller里面。

        但是如果我要add一本书籍应该怎么办呢?我应该在controller上面新增一个方法来处理这件事情吗? 不,原因在下面解释。因为它是DOM交互/操作的一部分。所以请把它放到directive(指令)里面。怎么做呢?很高兴你能问出这个问题。

 

三.DIRECTIVES(指令)

        到目前为止,在我们所编写的大量AngularJS应用中,应用中最主要的复杂部分都在directive(指令)中。有一个强大的工具可以用来操作和修改DOM,它也是我们这里需要讨论的内容。我们来提供一个按钮,用户通过它可以向service里面添加一本图书,以这一功能来结束此文。

        一个常见的反模式(按照本人愚见)是在controller里面添加DOM交互代码。Angular对directive的定义是一段代码片段,你可以用它来操作DOM,但是我觉得directive也是进行用户交互的很好选择。我们来扩展前面的例子,为用户提供一个按钮,通过这个按钮可以向service里面添加一本书籍。

md.directive( "addBookButton", [ 'Book', function( Book ) {
    return {
        restrict: "A",
            link: function( scope, element, attrs ) {
            element.bind( "click", function() {
                Book.addBook( { title: "Star Wars", author: "George Lucas" } );
            });
        }
    };
}]); 

        很简单的东西。我们创建了一个指令,它的核心目的是简单地向books列表中添加一本书籍,books已经注册在了我们的Book服务中。我们来把这个指令应用到我们的视图中。

<button add-book-button>Add book</button>

        如你所见,我们仅仅把指令当作一个元素属性来使用。每次点击这个按钮的时候,它都会把《Star Wars》(《星球大战》)这本书添加到我们的Book service中去。简单、轻松、模块化---并且易复用。好了,我们为什么不直接在控制器上面添加一个addBook之类的方法呢,比如说就像下面这样:

 $scope.addBook = function() {
     Book.addBook( { title: "Star Wars", author: "George Lucas" } );
 };

        这样我们也能获得同样的结果,对吧?是的,确实如此---但是这样做会带来一个重大的问题。一旦我需要在其它地方添加书籍,我必须拷贝这份代码(非 常un-DRY!)(译者注:DRY---Dont Repeat Yourself,貌似是Ruby所倡导的一个重要的编码原则。),或者进行重构(重构本身并不是什么不好的的事情)。通过直接构建一个指令的方式,我们 以后就没有必要担心这种事情了---同时下次再需要实现相同功能的时候完全不需要花任何时间。通过构建指令的方式来进行DOM交互和修改,随着业务需求的 不断介入,我们就可以立即腾出手来处理复杂性不断增加的应用了。这是相当不错的一件事情,因为它保证了我们可以更少地和自己的实现打架,并且可以一直编写 DRYer code。

        Angular的模块依赖哲学无疑让它成为了一款非同凡响的框架。它让我们能够以这样一种方式来编写我们的前端代码:我们不会干翻自己,也不会干翻框架---这可能是它最强大的力量。

        希望我已经充分说明了你应该在何时何地使用这几个Angular概念,从而能够更好地编写你自己的代码。

 

PS:

        1.工程目录结构:

        2.运行效果:

文章来源:http://damoqiongqiu.iteye.com/blog/1971204

  • 大小: 29.9 KB
  • 大小: 16.7 KB
分享到:
评论

相关推荐

    最新AngularJS开发宝典视频教程 后盾网AngularJS培训视频教程 后盾网.txt

    ├最新AngularJS开发宝典—第072讲 使用service创建自定义服务.mp4 ├最新AngularJS开发宝典—第073讲 SPA应用的路由使用分析.mp4 ├最新AngularJS开发宝典—第074讲 uiRouter默认路由规则操作.mp4 ├最新AngularJS...

    angularJS+requireJS实现controller及directive的按需加载示例

    总结以上知识点,文章围绕如何在AngularJS项目中实现controller和directive的按需加载,提供了一种结合RequireJS的解决方案。通过动态注册模块、异步加载文件和合理配置路由,能够有效提升大型应用的性能表现。这些...

    AngularJS开发下一代WEB应用

    Module是AngularJS的启动点,所有的controller、directive、service和filter等API都是定义在Module实例上的。开发者可以通过angular.module方法来创建和配置模块。 AngularJS中的双向数据绑定是其一大亮点,它允许...

    AngularJS UI Development

    - **模板与指令**:AngularJS中的UI开发主要依靠强大的模板系统和自定义指令(Directive)。模板允许开发者使用特定的语法来创建复杂的用户界面,而指令则可以用来扩展HTML的语义,使其能够执行更多的功能。 - **...

    angularJs demo 各种基本用法

    在"angularJs demo 各种基本用法"中,我们可以深入探讨以下几个关键概念:路由(router)、过滤器(filter)、服务(service)以及指令(diractive)。 **路由(Router)**: AngularJS的路由功能允许我们根据URL来...

    学习AngularJS-1.x.pdf

    十一、AngularJS Directive之间的通讯 * 让Directive之间互相通讯 * transclude 指令:在Directive之间传递数据 十二、总结 * 学习AngularJS的经验和教训 * 如何继续深入学习AngularJS 十三、深入学习AngularJS ...

    angularjs_angularjs_

    例如,我们可以在控制器中注入`$scope`和`DataService`,以展示如何使用封装的服务获取数据: ```javascript app.controller('HomeController', function($scope, DataService) { DataService.fetchData('api/data...

    angularjs前端框架

    - **模块注册**:通过`.controller()`、`.service()`、`.directive()`等方法向模块中添加控制器、服务和指令。 ##### 4. 指令系统 指令是AngularJS的一个重要概念,它允许开发者自定义HTML标记,实现复杂的行为和...

    AngularJS 中文API参考手册.zip_API_angularjs_angularjs api

    **AngularJS 中文API参考手册** ...以上只是AngularJS API中的一部分内容,中文API参考手册提供了更详细的信息,包括每个API的用法、参数、返回值等,是开发者深入理解和使用AngularJS的重要工具。

    Angularjs中controller的三种写法分享

    在Angular中,Directive、Service、Filter、Controller都是以工厂方法的方式给出,而工厂方法的参数名对应着该工厂方法依赖的Service。angularjs中controller其实就是一个方法,它有三种写法,下面来一起看看吧。 第...

    AngularJS学习手册 源代码

    在AngularJS中,我们可以使用`{{ }}`双括号语法将模型数据直接展示在视图上,同时,当模型数据发生变化时,视图也会实时更新。例如,`&lt;span&gt;{{message}}&lt;/span&gt;`会显示与`$scope.message`关联的值。 二、依赖注入 ...

    使用AngularJS编写较为优美的JavaScript代码指南

    在AngularJS中,我们可以使用`angular.module`函数创建和注册模块,然后在模块中定义服务、指令、过滤器等组件。 ```javascript var myApp = angular.module('myApp', []); myApp.controller('MyController', ...

    AngularJS笔记

    5. **国际化(I18n)与本地化(L10n)**:AngularJS支持多种语言和文化特性的显示,使其易于在国际化的环境中使用。 6. **服务(Service)**:服务是可重用的功能单元,如数据访问对象(DAO)、工厂和值提供者,用于封装...

    AngularJS快速入门教程

    - **指令(Directive)**:指令是AngularJS中扩展HTML的一种方式。通过自定义指令,可以轻松地向HTML文档中添加新的行为。 - **过滤器(Filter)**:过滤器用于格式化数据显示给用户。例如,可以创建一个过滤器来格式化...

    angularjs 环境安装

    **AngularJS 环境安装指南** ...在开发过程中,持续学习和理解AngularJS的核心概念,如模块(module)、控制器(controller)、服务(service)和指令(directive),将有助于你更深入地掌握这个框架。

    AngularJS UI Development 随书代码

    《AngularJS UI Development》这本书是关于使用AngularJS框架进行用户界面开发的专业指南,随书附带的代码资源库名为"AngularUI-Code-master"。这个压缩包中的代码旨在帮助读者深入理解并实践AngularJS在构建现代Web...

    Dependency Injection with AngularJS

    2. 服务:在AngularJS中,服务(Service)是一种可复用的代码块,可以被注入到其他控制器(Controller)、指令(Directive)、过滤器(Filter)等中。 3. 提供者(Provider):提供者是用于配置依赖项的一个高级抽象...

    angularjs loading遮罩层

    在本文中,我们将深入探讨如何在AngularJS应用中实现一个加载遮罩层,不依赖于jQuery或特定的图片资源如gif。我们将主要关注如何利用AngularJS的模块化、指令和服务来构建这一功能,并结合Bootstrap样式增强用户体验...

Global site tag (gtag.js) - Google Analytics