LOGv:20171214

カスタムサービス

AngularJSで独自にサービスを作りたい場合は

といったメソッドを利用して作成します。
このうち、value、factory、serviceの3つは内部的に直接的、間接的にproviderを呼んでいるだけなので、providerでも3つのメソッドと同様のことが可能です。

└ $provide#provider
└ $provide#factory
├ $provide#service
└ $provide#value

$provide#providerレシピ

前述の通り、value、factory、serviceは内部でproviderを呼んでいるだけなので、
3つのメソッドと同様のことが出来ます。
3つのメソッドとの大きな違いはconfigでパラメータの設定をすることができることです。
※ providerでサービスを登録する場合、オブジェクトを返す$getメソッドを定義する必要があります。
※ configにプロバイダーをインジェクトするときの名前は
「サービス名 + Provider」になります。

myApp = angular.module('myApp',[])

_myService = ->
@val = 'hoge'
@$get = ->
return {
message : @val + '!!!!!'
}
return

myApp.provider('myService1',_myService)
myApp.provider('myService2',_myService)

myApp.config(['myService1Provider','myService2Provider',(sp1,sp2)->
sp1.val = 'fuga'
sp2.val = 'piyo'
return
])

myApp.run((myService1,myService2)->
console.log myService1.message
# fuga!!!!!
console.log myService2.message
# piyo!!!!!
return
)

 インスタンスを返す例

class myClass
constructor : ->
message : -> 'hoge!!!!'

myApp = angular.module('myApp',[])

myApp.provider('myService',['$injector',($injector)->
@$get = ->
return $injector.instantiate(myClass)
return
])

myApp.run((myService)->
console.log myService.message()
# hoge!!!!
return
)

値を返す例

myApp = angular.module('myApp',[])

myApp.provider('myService',['$injector',($injector)->
@$get = ->
return 'hoge'
return
])

myApp.run((myService)->
console.log myService
# hoge
return
)

$provide#factoryレシピ

オブジェクト(オブジェクトを登録)を返します。
返されるものは数値でも関数でも配列でもクラスでもオブジェクトであればなんでもいいです。
valueとの違いはDIでサービスをインジェクト出来る点です。
クラスのインスタンスを返せばserviceと同じです。

myApp = angular.module('myApp',[])
myApp.factory('myService1',[->
return 'hello!'
])

myApp.factory('myService2',['myService1',(myService1)->
return -> myService1 + 'guys!'
])

myApp.run((myService2)->
console.log myService2()
return
)

$provide#serviceレシピ

クラスのインスタンス(コンストラクタ関数を登録)を返します。
factoryと同じくDIでサービスをインジェクトできます。

class myClass
constructor : ->
message : -> 'hello! guys!'

myApp = angular.module('myApp',[])
myApp.service('myService',[myClass])

myApp.run((myService)->
console.log myService.message()
return
)

$provide#valueレシピ

オブジェクトを返します。
valueはDIでサービスをインジェクトすることが出来ないため、単純な共通などに使うのがいいです。

myApp = angular.module('myApp',[])
myApp.value('text','hello!')

myApp.provider('myProvider',['text',(text)->
@$get = -> {}
return
])

myApp.run((text)->
console.log text
return
)

インジェクトするとエラーが発生する

myApp = angular.module('myApp',[])
myApp.value('text','hello!')

myApp.provider('myProvider',['text',(text)->
@$get = -> {}
return
])

myApp.run((text)->
console.log text
return
)

# エラー

$provide#constantレシピ

constantはvalue、factory、serviceと違いproviderを利用していません。

# constantの定義
function constant(name, value) {
assertNotHasOwnProperty(name, 'constant');
providerCache[name] = value;
instanceCache[name] = value;
}

constantはvalueに似ていますが

  • DIでサービスをインジェクトすることができる
  • 利用可能なタイミングが他のレシピより早いため、configへのインジェクトが可能

という点が違います。
また、decoratorメソッドで内容を上書きすることが出来ません。

constant(定数)ですが、参照渡しのものに関しては値を変更出来ます。

myApp = angular.module('myApp',[])
myApp.constant('text','hello! guys!')
myApp.constant('obj',{
a : 1
})
myApp.constant('arr',[10])

myApp.config(['text','obj','arr',(text,obj,arr)->
text = 'goodbye guys!'
obj.a = 2
arr = [22]
return
])

myApp.run((text,obj,arr)->
console.log text
# hello! guys!
console.log obj.a
# 2
console.log arr[0]
# 10
)

valueはコントローラーやサービスで利用、constantはディレクティブやプロバイダの設定に利用すれば良いようです。
AngularJS リファレンス 参照

$provide#decorator

定義されているサービスをフックします。

myApp = angular.module('myApp',[])
myApp.value('text','hello! guys!')

myApp.config(($provide)->
$provide.decorator('text',($delegate)->
console.log $delegate + '2'
return
)
return
)

myApp.run((text)->
console.log text
# hello! guys!2
)

open close