Closed dcramer closed 8 years ago
Do you have a code example? I believe that standard resolvers using either ng-router
or ui-router
should just work. Perhaps I'm misunderstanding what you're trying to do though.
Sorry what I mean is it'd be nice if I could bundle them inside of the controller somehow ;)
Here's the pattern we adopted: https://github.com/dropbox/changes/blob/master/static/js/states/planList.js
A Classy controller returns itself, so you could do this:
define(['app'], function(app) {
'use strict';
return {
parent: 'layout',
url: '/plans/',
templateUrl: 'partials/plan-list.html',
controller: app.cC({
inject: ['$scope', 'planList', 'Collection'],
init: function() {
this.$.plans = new this.Collection(this.$, this.planList.data);
}
}),
resolve: {
planList: function($http) {
return $http.get('/api/0/plans/');
}
}
};
});
Or are you looking to move your route information inside of the Classy controller?
edit: cC is just a shortcut for classy.controller, you can use either.
I guess what I'm proposing is something-like-resolvers should be part of a controller/class API.
Realistically they're used for initialization a lot of time, and the dirty work you have to do to hide the controller/show it (without resolvers) is just gross.
Ah, so this would be a separate resolver to the one the router provides (and would happen after the router's resolver if the router had a resolve defined)? It's not something that I've thought about to be honest. It's an interesting proposal, I'll have a think about it and get back to you tomorrow after some sleep (I'm GMT).
This is exactly what I'm looking for as well. Resolves are promises that when completed are injected into the controller. I've wanted to keep them in the controller for a long while. So it would match with either the inject
section, or something else.
Does anybody want to propose an API for this? Should the resolvers re-use the class-wide injected dependencies or should each resolver inject it's own dependencies?
I think the default would be to use the classes inject
property when referencing dependencies, with potential for an optional way of declaring that a resolver should derive its dependencies independently.
As for an API, I think something like this perhaps?
app.classy.controller
name: 'PlanController'
inject: ['$scope', 'planList']
resolve:
plans: -> @planList
Under the hood there's a few things going on here:
planList
would have to be either an angular service with a get
method, or just a pure function that encapsulated $http.get('/api/0/plans/');
(in either case, the return value would be a promise).resolve.plans
would become $http.get('/api/0/plans/').data
)The key pieces here are auto resolving the promise and attaching the result to the scope.
Also, given that angular works reasonably well with promises referenced inside templates and will automatically render values once promises are resolved, classy could do the simple thing and just invoke the appropriate resolve
key and map the promise onto the $scope
Why couldn't the passed resolve just be passed into the inject
config, similar to how you would inject it into a regular Angular controller?
inject: ['$scope', '$rootScope', '$kinvey', '$state', '$modal', '$timeout', 'User'
init: function() {
this.user = User;
}
Why do we need another level of abstraction?
FYI a lot of the time I dont actually want to bind my resolver to the scope. I generally manipulate it/use it to populate something else.
I think it would be a mistake to assume auto binding resolvers to the scope is a common idiom (it might be, but IMO its an incorrect one)
@dcramer: Fair enough. :smile:
I'm using the resolved values directly in some of my controllers, mainly just to prevent route change before data is ready. Other times I'm using a service where the classy API works just great.
Ok, I think that the most likely outcome in the short-term is that there will be an API available for extending Classy (see #6, it would be good to have more peoples feedback on what this API should look like). This will allow resolvers to be implemented as a Classy plugin.
If there is an obviously favoured plugin for doing resolvers with Classy and it is used by enough people then it can be merged into the core of Classy.
@dcramer I really liked your approach to declaring controllers within a state. Did you come up with that convention or is that a common Angular UI Route practice?
@demetriusnunes I came up with it. I'm not a JS person so I just structure things in a logical way. One of the reasons I chose Angular of Ember in a different project was because it gave me these choices :)
It should now be possible to create a Classy plugin that supports resolvers. Just make sure your using the version of Classy from the develop branch (not master).
Take a look here to see how to write a Classy plugin: coffeescript, javascript
When you've created a plugin then you can add the plugin to your app's module definition:
var app = angular.module('app', ['classy', 'classy-yourPlugin']);
Classy itself is now modular and written as plugins, so you could also take a look at the source for guidance on how to write a plugin: https://github.com/davej/angular-classy/blob/develop/angular-classy.coffee
Anybody want to have a go creating a resolve plugin? I'm here to help if anything isn't clear (or if the plugin doesn't expose enough functionality to write a resolve plugin properly).
I was just looking for something like this and realizing AngularJS didn't support it I immediately thought of classy. Support for resolvers as a property on the class would be absolutely awesome. This is exactly where resolvers should go the vast majority of the time.
Closing this as Classy won't support it in core. If anybody wants help creating a plugin then just @
me.
Not sure if this is reasonable or not, but we bundle our controllers (using ui-router) into a state, which also lets us easily encapsulate resolvers.
The way we've been doing it resolvers are purely "load this before rendering" (i.e. make API request).