Open Iristyle opened 11 years ago
To make this a little more clear. The Order
service I'm injecting looks like this
'use strict'
angular.module('app').factory('Order',
[
'$resource', '$location', 'Config',
($resource, $location, Config) ->
base = Config.Values.ServiceBase
uri = "#{$location.protocol()}:#{base}/orders/:orderId"
return $resource(uri, { orderId: '@Id' })
])
In my custom type definitions I have the definitions for $resource
// http://docs.angularjs.org/api/ngResource.$resource
{
"name": "$resource",
"enabled": true,
"constructors": [
{"args": [{"name": "url"}]},
{"args": [{"name": "url"}, {"name": "{paramDefaultsHash}"}]},
{"args": [{"name": "url"}, {"name": "{paramDefaultsHash}"}, {"name": "{actionsHash}"}]}
],
"static_properties": [],
"static_methods": [],
"instance_properties": [],
// TODO: handle $prefixed actions
// var user = User.get({userId:123}, function() {
// user.abc = true;
// user.$save();
// });
// non-GET instance actions: instance.$action([parameters], [success], [error])
"instance_methods": [
{"name": "delete", "args": [{"name": "postData"}]},
{"name": "delete", "args": [{"name": "{paramsHash}"}, {"name": "postData"}]},
{"name": "delete", "args": [{"name": "{paramsHash}"}, {"name": "postData"}, {"name": "() -> successFn"}]},
{"name": "delete", "args": [{"name": "{paramsHash}"}, {"name": "postData"}, {"name": "() -> successFn"}, {"name": "() -> errorFn"}]},
{"name": "get", "args": [{"name": "{paramsHash}"}]},
{"name": "get", "args": [{"name": "{paramsHash}"}, {"name": "() -> successFn"}]},
{"name": "get", "args": [{"name": "{paramsHash}"}, {"name": "() -> successFn"}, {"name": "() -> errorFn"}]},
{"name": "query", "args": [{"name": "{paramsHash}"}]},
{"name": "query", "args": [{"name": "{paramsHash}"}, {"name": "() -> successFn"}]},
{"name": "query", "args": [{"name": "{paramsHash}"}, {"name": "() -> successFn"}, {"name": "() -> errorFn"}]},
{"name": "remove", "args": [{"name": "postData"}]},
{"name": "remove", "args": [{"name": "{paramsHash}"}, {"name": "postData"}]},
{"name": "remove", "args": [{"name": "{paramsHash}"}, {"name": "postData"}, {"name": "() -> successFn"}]},
{"name": "remove", "args": [{"name": "{paramsHash}"}, {"name": "postData"}, {"name": "() -> successFn"}, {"name": "() -> errorFn"}]},
{"name": "save", "args": [{"name": "postData"}]},
{"name": "save", "args": [{"name": "{paramsHash}"}, {"name": "postData"}]},
{"name": "save", "args": [{"name": "{paramsHash}"}, {"name": "postData"}, {"name": "() -> successFn"}]},
{"name": "save", "args": [{"name": "{paramsHash}"}, {"name": "postData"}, {"name": "() -> successFn"}, {"name": "() -> errorFn"}]}
]
}
I would expect completions over my Order
instance above to pick up these methods from $resource
. This is a more complicated example, but I hope you get the idea.
One way I thought to make the tools do what I want is to do something like classifying Order
... but I still don't get proper completion on my Order
class.
'use strict'
class Order
# @param [$resource] resource
# @param [$location] location
# @param [Config] Config
# @returns [$resource]
constructor: (resource, location, Config) ->
base = Config.Values.ServiceBase
uri = "#{location.protocol()}:#{base}/orders/:orderId"
location.absUrl()
return resource(uri, { orderId: '@Id' })
angular.module('app').factory('Order',
[
'$resource', '$location', 'Config',
($resource, $location, Config) ->
o = new Order($resource, $location, $Config)
# still nothing here for
#o.
])
So almost there, but not quite. I've also tried the above as a non-constructor method like foo
or @foo
and nada. I can't use something like class Order extends $resource
either -- even if that were semantically correct, autocomplete doesn't seem to work. The only thing I can do at the moment to force the hand of the autocompletion is to use a line like this... then I don't need Order
to appear in a class
(and if it is in a class, I lose any other properties / methods I might have for Order
)
o = new Order($resource, $location, $Config) # [$resource]
BTW -- I have all of the AngularJS mapping in a CoffeeComplete Plus Custom Types.sublime-settings
locally... testing out what I can do to improve the overall experience. It's pretty good, but there are a few rough edges (most of the other PRs I've submitted).
This might be a bit tricky, but I thought I'd suggest it anyhow.
AngularJS has a module and dependency injection system, where you register a type by name, and essentially return a function used to construct your type.
Here's the docs on controllers and how you would generally register one with
angular.module
.This plugin would be totally amazing if it could map the injected dependency back to the function that's returned.
This may sound a bit abstract -- here's a simple example.
The name of the controller being registered is
OrderCtrl
. It has the dependencies$scope
,$routeParams
andOrder
(in this case, an Angularservice
) injected, and they are mapped to variables of the same name. Note that Angular has two syntaxes for it's DI system, but the one I'm using here is preferred, for minification purposes (normally a variable named$scope
is good enough to have Angular find it... BUT.. that name is changed during minification).There are a bunch of different constructs in Angular -- but the one that would be the most advantageous to have autocomplete over would be services (so functions registered by
module.service
,module.provider
,module.factory
ormodule.value
). Generally the only thing depending on an Angular controller is some data-binding code in HTML... but it's common for Angular services to be used across many controllers, directives, etc.Does that make sense? Not sure how feasible this is, but man would it be awesome to have... and hey, maybe there's already a way to make this work that I'm not aware of.
If none of this was clear, please let me know.
Thanks!
And btw -- I maintain a package for AngularJS snippets in CoffeeScript, but the snippet system is clearly a bit dumbed down compared to the capabilities here.. so I might work on trying to bring the snippets in here as type definitions.