扯淡的话----------作为一个老魔兽玩家,我很喜欢将写代码和玩游戏进行对比,在使用不同的框架时,就好像我们在切换天赋技能,拿盗贼来说,敏锐天赋有个技能叫暗影之舞(好久没玩,不知道还在不),开了之后允许在非潜行状态下使用潜行技能,比如偷袭,锁喉什么的,这就好像在框架里我们需要知道哪个方法可以在什么状态下使用,在什么时间用,比如盗贼内战时,高手会用消失来躲致盲,在需要爆发时,贼们也会消失进入潜行来一波爆发。。。。。所以知道我们可以做什么,怎么样做,什么时间做,是成为高手必须的修行,好了,废话不多说,进入正题。

Angular应用是由许多对象组成,这些对象根据一定的关系被关联在一起,大多数情况下我们并不需要关心它们是如何被组织在一起,以及相互之间是如何进行协作的,但想要更亲近angular,就必须了解这一过程。
大体上来说angular的对象可以被分为两类,一类是像services这种由开发者定义的,用来提供应用所需要的公共API,一类是由angular框架定义好的具有特定用途的对象,比如controller、filter、directive等。那么这些对象是如何被定义出来的?除了injector外别无它法,但是对于injector来说,它需要知道如何去定义这些对象,对于内置的那些对象来说,我们当然不需要插手,angular为此暴露了5个API,分别是value(),service(),factory(),constant(),以及最为强大的provider(),前四个其实就是provider()的语法糖。虽然对象的创建是由injector来完成,但这5个方法却是angular模块的方法,也就是说我们在调用的时候需要在模块上去调用,例1:

var myModule = angular(“myModule”,[]); 
myModule.value(“name”,”superMan”);

在angular中,所有的服务都是单例对象,也就是说它们只会被调用一次,之后在injector中会保存服务的引用,在需要的时候将其当作依赖注入进去。
一、value()
例1中我们已经定义了一个服务,那么我们就可以在任何需要的时候把它注入到我们的控制器中,例2:

myModule.controller(“myController”,[“name”,function(name){
    this.name = name;
}]);
<body ng-controller = “myController as con”>
    Name:{{con.name}}
</body>

这样我们就可以成功的拿到这个注册的名字”superMan”,并且可以在视图中正确的读到它。
它就是如此的简单。
二、constant()
这个方法和value()一样的简单,唯一的不同是,constant()注册的值可以在angular运行的配置阶段访问到。例3:

myModule.constant(“prefix”,”ECS”);
myModule.config([“prefix”,function(pre){
    //这里的pre将会被正确的访问
}]);
myModule.config([“name”,function(name){
    //这里去访问name将会抛出错误,因为此时服务都还没有被注册
}]);

angular应用的生命周期被分为配置和运行两大阶段,在配置阶段,我们所写的服务都还没有注册进来,所以在这个时候去访问通过value()方法注册的值,是不可访问到的。当然constant()注册的值在运行阶段也是可以被正确的访问的。也就是说它们一个是全周期可见,一个是只有运行阶段可见。
三、factory()
以上两个方法都非常的简单,注册的值也一样的简单,实际情况中我们需要一些更为复杂的服务来提供更加健全的功能。Factory()同它们相比具有更强的能力,1、通过依赖注入可以引用到其它的服务。2、初始化服务。3、延迟加载服务,也就是说在需要的时候angular才去初始化。例4:

myModule.factory("name",function nameFactory(){
    return "superMan";
});

我们将例1中通过value()注册的值用factory()重写,这里我们用到了函数,这个函数可以接受一个或多个参数,只要这些参数已经被angular注册,它们就能被当作依赖被正确的加载进来,函数的返回值将被作为服务的实例被其引用到。这就给我们提供了更多的可能,我们可以返回一个简单值 ,当然也可以返回个对象或函数,总之看你需要。例5:

myModule.factory("fullName",["name",function fullNameFactory(name){
    var firstName = "XX";
    var fn = function(f,l){
        return f + l;
    }
    return {
        name:fn(firstName,name)
    }
}]);

在这里,函数的名字不是必须的,但是最好给它起一个能够很容易辨识的名字,这在调试程序时将会非常有用,一旦出错,你可以很轻易的在堆栈追踪中发现它。
四、service()
在面向对象的开发中,我们经常会用到自定义的类,当然,我们可以使用factory()方法来把这些类注册为服务,例6:

function Person(name){
    this.name  = name;
    this.speak = function(){
        console.log("my name is " + this.name);
    }
}
myModule.factory("person",function person(name){
    return new Person(name);
}]);

在创建服务时,service()方法和factory()方法唯一的不同之处就是它使用new运算符来给我们实例化一个对象,也就是这个时候我们应该给service()传入一个构造函数,构造函数可以接受0个或多个参数,这些参数从哪来?当然是依赖注入,既然在factory()中我们都可以依赖注入,在service()中当然也可以,用service()来重写例6:

myModule.service("person",Person]);

一目了然,无需多言。
五、provider()
前面说过,以上4种方法都是provider()的语法糖,也就是说上面4种方法具有的能力,provider()都具有。Providr()的能力是最强大的,但在实际开发中有时候会显的矫枉过正,永远记住,只选最适合你的。
对于provider()而言,它必须有一个$get()方法,这是区别于上面4种方法最为明显的地方,对于$get()的参数,可能通过依赖注入来获取,这个函数就像factory()的工厂函数,实际上对于factory()而言,angular会自动给它的函数设置一个空的$get()方法。
另外,前面我们提到过angular应用生命周期的2个阶段,如同constant()方法,provider()方法当然也可以在配置阶段运行,因此,对于provider()它最适用的场景就是在应该启动前给我们暴露一些API,以便我们可以通过这些API对应用进行配置。它注册的服务应该是我们希望在不同的应用间可以重用,且服务的行为在各有应用间非常一致,或者说变化非常小。
例7:

myModule.provider("speakName",function speakNameProvider(){
var firstName = "";
this.addFirstName = function(f){
    console.log(“my firstName is:” + f);
    firstName = f;
}
    this.$get= ["name",function speakNameFactory(name){
        var fullName = firstName + name;
        return new Person(fullName);
    }];
});

假如我们希望在应用配置阶段加上一个姓,那么就可以通过暴露的API实现

myModule.config(["speakNameProvider",function(speakNameProvider){
    speakNameProvider.addFirstName("XXX");
}]);

回到开头说的,angular的对象分为两类,对于我们可以定义的,前面已经介绍完了,对于angular已经内置的一些对象,我们在使用时候必须遵循它的规则,比如controller、directive、filter等。当然我们定义好的这些服务可以被作为依赖注入到这些特殊对象中,比如:

myModule.directive("myName",function myName(name){
    return {
        restrict:"EA",scope:{},link:function(scope,ele,attrs){
            ele.text("name:" + name);
        }
    }
}]);

angular中如何创建出需要的service的更多相关文章

  1. Android Studio是否支持用于Android UI设计的AngularJS?

    我对AndroidStudio有疑问:AS在设计XML文件时是否支持AngularJS代码,例如:对于小动画或效果?

  2. android – 如何使用ClientID和ClientSecret在Phonegap中使用Angularjs登录Google OAuth2

    我正尝试使用Angularjs(使用IonicFramework)通过GoogleOAuth2从我的Phonegap应用程序登录.目前我正在使用http://phonegap-tips.com/articles/google-api-oauth-with-phonegaps-inappbrowser.html进行登录.但是当我使用Angular-UI-RouterforIonic时,它正在创建非常

  3. 利用require.js与angular搭建spa应用的方法实例

    这篇文章主要给大家介绍了关于利用require.js与angular搭建spa应用的方法实例,文中通过示例代码给大家介绍的非常详细,对大家的理解和学习具有一定的参考学习价值,需要的朋友们下面跟着小编来一起看看吧。

  4. 详解Angular动态组件

    本文主要介绍了Angular动态组件,对此感兴趣的同学,可以亲自实验一下。

  5. 详解如何使用webpack+es6开发angular1.x

    本篇文章主要介绍了详解如何使用webpack+es6开发angular1.x,具有一定的参考价值,有兴趣的可以了解一下

  6. angular2系列之路由转场动画的示例代码

    本篇文章主要介绍了angular2系列之路由转场动画的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  7. 一种angular的方法级的缓存注解(装饰器)

    本篇文章主要介绍了一种angular的方法级的缓存注解(装饰器),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  8. 动手写一个angular版本的Message组件的方法

    本篇文章主要介绍了动手写一个angular版本的Message组件的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  9. angular forEach方法遍历源码解读

    这篇文章主要为大家详细了angular forEach方法遍历源码,forEach()方法用于遍历对象或数组,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. Angular的MVC和作用域

    本文主要Angular的MVC和作用域进行详细分析介绍,具有一定的参考价值,下面跟着小编一起来看下吧

随机推荐

  1. Angular2 innerHtml删除样式

    我正在使用innerHtml并在我的cms中设置html,响应似乎没问题,如果我这样打印:{{poi.content}}它给了我正确的内容:``但是当我使用[innerHtml]=“poi.content”时,它会给我这个html:当我使用[innerHtml]时,有谁知道为什么它会剥离我的样式Angular2清理动态添加的HTML,样式,……

  2. 为Angular根组件/模块指定@Input()参数

    我有3个根组件,由根AppModule引导.你如何为其中一个组件指定@input()参数?也不由AppModalComponent获取:它是未定义的.据我所知,你不能将@input()传递给bootstraped组件.但您可以使用其他方法来做到这一点–将值作为属性传递.index.html:app.component.ts:

  3. angular-ui-bootstrap – 如何为angular ui-bootstrap tabs指令指定href参数

    我正在使用角度ui-bootstrap库,但我不知道如何为每个选项卡指定自定义href.在角度ui-bootstrap文档中,指定了一个可选参数select(),但我不知道如何使用它来自定义每个选项卡的链接另一种重新定义问题的方法是如何使用带有角度ui-bootstrap选项卡的路由我希望现在还不算太晚,但我今天遇到了同样的问题.你可以通过以下方式实现:1)在控制器中定义选项卡href:2)声明一个函数来改变控制器中的散列:3)使用以下标记:我不确定这是否是最好的方法,我很乐意听取别人的意见.

  4. 离子框架 – 标签内部的ng-click不起作用

    >为什么标签标签内的按钮不起作用?>但是标签外的按钮(登陆)工作正常,为什么?>请帮我解决这个问题.我需要在点击时做出回复按钮workingdemo解决方案就是不要为物品使用标签.而只是使用divHTML

  5. Angular 2:将值传递给路由数据解析

    我正在尝试编写一个DataResolver服务,允许Angular2路由器在初始化组件之前预加载数据.解析器需要调用不同的API端点来获取适合于正在加载的路由的数据.我正在构建一个通用解析器,而不是为我的许多组件中的每个组件设置一个解析器.因此,我想在路由定义中传递指向正确端点的自定义输入.例如,考虑以下路线:app.routes.ts在第一个实例中,解析器需要调用/path/to/resourc

  6. angularjs – 解释ngModel管道,解析器,格式化程序,viewChangeListeners和$watchers的顺序

    换句话说:如果在模型更新之前触发了“ng-change”,我可以理解,但是我很难理解在更新模型之后以及在完成填充更改之前触发函数绑定属性.如果您读到这里:祝贺并感谢您的耐心等待!

  7. 角度5模板形式检测形式有效性状态的变化

    为了拥有一个可以监听其包含的表单的有效性状态的变化的组件并执行某些组件的方法,是reactiveforms的方法吗?

  8. Angular 2 CSV文件下载

    我在springboot应用程序中有我的后端,从那里我返回一个.csv文件WheniamhittingtheURLinbrowsercsvfileisgettingdownloaded.现在我试图从我的角度2应用程序中点击此URL,代码是这样的:零件:服务:我正在下载文件,但它像ActuallyitshouldbeBook.csv请指导我缺少的东西.有一种解决方法,但您需要创建一个页面上的元

  9. angularjs – Angular UI-Grid:过滤后如何获取总项数

    提前致谢:)你应该避免使用jQuery并与API进行交互.首先需要在网格创建事件中保存对API的引用.您应该已经知道总行数.您可以使用以下命令获取可见/已过滤行数:要么您可以使用以下命令获取所选行的数量:

  10. angularjs – 迁移gulp进程以包含typescript

    或者我应该使用tsc作为我的主要构建工具,让它解决依赖关系,创建映射文件并制作捆绑包?

返回
顶部