Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

support resolve option for directives #2095

Closed
ewinslow opened this issue Mar 3, 2013 · 95 comments
Closed

support resolve option for directives #2095

ewinslow opened this issue Mar 3, 2013 · 95 comments

Comments

@ewinslow
Copy link
Contributor

ewinslow commented Mar 3, 2013

They have template and controller options. Seems consistent to give them a resolve option as well, just like routes, unless there's some philosophical reason for leaving them out in this case...

@IgorMinar
Copy link
Contributor

We want directives to be as synchronous or as close to synchronous as possible so that we reduce user perceived flicker and jank. Delaying directive resolution would work against this goal.

@IgorMinar
Copy link
Contributor

I'm closing this, please feel free to reopen if you have suggestions on how to avoid the flicker issue.

@ewinslow
Copy link
Contributor Author

The only solutions I can come up with would immediately lead to very poor performance due to the delays in rendering (e.g., block parent directive rendering on child directive resolution). Even so, I think there are certain times where "flicker" is acceptable (e.g. late-loading comments below a blog) and would like the freedom to code my controller in a synchronous fashion even though the data is fetched asynchronously.

@arush
Copy link

arush commented Apr 22, 2013

This is my BIGGEST gripe with Angular. I think there should be a concept of a loading state in angular given 99% of projects are likely to need a loading state of sorts. Let people define their own templateUrl for the directive while it's in a loading state.

I'm constantly having to deal with directives that can't cope with asynchronously loading data. Even angularStrap can't deal with bs-typeahead="obj.someArray" being asynchronously loaded.

e.g.

... resolve: [...] resolveTemplate: '<div style="width:100px; height: 100px; background: url('/images/loader.gif') 50% 50% transparent no-repeat"></div>' ...

It would be wise to assume that asynchronous developers are going to want to put loading gifs in their apps. Why not make it easy? Without being natively , more Angular apps are going to look janky

@ultrawebsites
Copy link

In my humble opinion, there definitely needs to be something done to simplify handling asynchronous data and directives (it is driving me insane too) - everyone keeps on saying how DOM manipulation should be done in directives, but often DOM manipulation in directives depends on asynchronous data having been loaded first, so given this I don't understand how/why directives are designed to be 'as close to synchronous as possible'?

I am relatively new to Angular, and maybe I just need to be pointed to a good article on directives with asynchronous data, but 'setTimeout' just doesn't cut it, and from what I understand there is "no way to know for sure when a directive has finished loading" (eg. can't use viewContentLoaded), so I'm unclear how it should be handled (and it doesn't make sense to me currently either).

Whether there is a "loading state" or perhaps better still a way of knowing when a directive has finished loading, I don't know, but I'd love to know how this should be handled the 'Angular way'.

@arush
Copy link

arush commented Apr 25, 2013

Matt,

I agree, it is counter-intuitive.

They way we currently deal with the async loading is we always have to wrap
our directive controller/link logic in promise.then statements. Sometimes
we also need to implement $watch. This means more strain on the CPU, and
hence more 'jank' which is the exact thing we are supposed to be avoiding
with 'synchronous' directives.

It would be a simple win-win fix just to add a 'resolve' state to
directives, with a 'resolveTemplateUrl' and 'resolveTemplate'. I could
build this as a universal directive, but it seems so overkill, it should
just be native. It doesn't harm anyone who doesn't want to use it!


Arush Sehgal
CTO, BRANDiD
mobile: +44 7917 138 230
twitter: @arush http://www.twitter.com/arush
skype: arushsehgal

twitter: founders.getbrandid.com

BRANDiD is a Seedcamp http://www.seedcamp.com/ company

Follow us on AngelList: angel.co/brandid

The information contained in this email is intended for the named recipient
(s) only. It may also be privileged & confidential. If you are not an
intended recipient, you must not copy, distribute or take any action in
reliance upon it. No warranties or assurances are made in relation to the
safety & content of this email & any attachments, no liability is accepted
for any consequences arising from it. Please ensure you activate an up to
date virus checker prior to opening any attachments.

On Thu, Apr 25, 2013 at 2:35 AM, Matt Jensen [email protected]:

In my humble opinion, there definitely needs to be something done to
simplify handling asynchronous data and directives (it is driving me insane
too) - everyone keeps on saying how DOM manipulation should be done in
directives, but often DOM manipulation in directives depends on
asynchronous data having been loaded first, so given this I don't
understand how/why directives are designed to be 'as close to synchronous
as possible'?

I am relatively new to Angular, and maybe I just need to be pointed to a
good article on directives with asynchronous data, but 'setTimeout' just
doesn't cut it, and from what I understand there is "no way to know for
sure when a directive has finished loading" (eg. can't use
viewContentLoaded), so I'm unclear how it should be handled (and it doesn't
make sense to me currently either).

Whether there is a "loading state" or perhaps better still a way of
knowing when a directive has finished loading, I don't know, but I'd
love to know how this should be handled the 'Angular way'.


Reply to this email directly or view it on GitHubhttps://github.com//issues/2095#issuecomment-16984268
.

@inscapist
Copy link

it would be a great feature to have!

@georgiosd
Copy link

I agree it would be a good idea to facilitate a loading state + resolve for directives

@troygoode
Copy link

👍

@j8
Copy link

j8 commented Dec 28, 2013

+1 Yeap, just dealing with a lot of async data and promises, resolve in directive will defiantly enhance user usability

@kbanman
Copy link

kbanman commented Jan 20, 2014

+1

@JordyMoos
Copy link

+1 here

@ghost
Copy link

ghost commented Jan 30, 2014

+1. @IgorMinar, the original reason for closing doesn't seem like a complete explanation. Lots of things can cause jankiness and flickering, ng-cloak was added for that purpose, I thought.

@kuraga
Copy link

kuraga commented Feb 4, 2014

+1 for resolve option for directives

@ewinslow
Copy link
Contributor Author

ewinslow commented Feb 4, 2014

I have a implemented a lazy-loading mechanism which hijacks the route resolver to crawl a template looking for directives, making sure those directives and their dependencies are loaded, then does so recursively in the directives' templates and so on. Only once all the dependencies are loaded does the route resolve, so there's no flicker. Angular could do something similar out of the box? It sounds like async support is on the table for 2.0 so I'm guess we'll see some kind of solution then...

@eggers
Copy link

eggers commented Feb 5, 2014

+1

I am looking for an easy way to have local loading states, and having a resolve function on a directive would solve the problem.

@kuraga
Copy link

kuraga commented Feb 7, 2014

I'm pretty new in Angular but I can't understand at all: suppose I use a directive to display information I got via $http. It sounds that I need resolve here, no?

And what's the difference between controllers and directives here?

@ewinslow where can we see your code?

@yelvert
Copy link

yelvert commented Feb 7, 2014

+1

@ewinslow
Copy link
Contributor Author

ewinslow commented Feb 8, 2014

@kuraga https://github.com/ewinslow/ng-require is the lazy-loading library. AMD-based.

https://github.com/ewinslow/ng-elgg is an example library that depends on it.

@ArdentZeal
Copy link

+1

1 similar comment
@JakobJingleheimer
Copy link

👍

@jeffwhelpley
Copy link

While I think directives should not rely on resolve() by default, it should be an option.

@ericsteele
Copy link

+1

@OnkelTem
Copy link
Contributor

OnkelTem commented Jun 8, 2014

Looks like everyone needs this feature but no one suggests a solution on how to workaround the lack of resolve. Please can somebody provide an example? I just don't get how to populate directive with data from $http.

And of course +1 for the feature.

@JakobJingleheimer
Copy link

@OnkelTem, There are a couple ways:

  1. Use ngRoute's (or UiRouter's) resolve method, and inject its data into a controller.
  2. Use ngIf on an ancestor element of the directive needing data, and make the data request within a controller (ngIf will automatically engage the target directive once the expression it's observing becomes truthy). <div ng-if="my.data"> <div foo="my.data"></div> </div>

You probably should not inject $http into the directive, but here's how to do it:

app.directive('foo', ['$http', function FooDirective($http) {
  $http.get('…').success(fn(){});
  return {
    link: function postLink(scope, element, attrs) { }
  };
}]);

@ds82
Copy link

ds82 commented Jul 4, 2014

Still looking for a clean solution for this one. Currently I manually delay the initialization of my directives until all dependencies are resolved. That results in really smelly code ..

@caitp
Copy link
Contributor

caitp commented Jul 4, 2014

You could put together a PR for this. I can't promise it would land, but I have some ideas how you could do it.

It would be something like this:

  1. resolve would require a controller (we have no way to inject locals into link functions, and I don't think it's that useful to add support for that)
  2. for each key/value pair in the resolve collection, get the result of invoking with the injector. If the result is a promise, we must use the async path (similar to templateUrl).
  3. use these key/value pairs during controller instantiation by extending the locals object.

As Igor has said, this is probably not desirable and not necessarily likely to land, but if you can implement it elegantly and demonstrate that it's actually useful, there's a chance it could land since there seems to be considerable interest.

@thinkjones
Copy link

+1

1 similar comment
@AntonSotirov
Copy link

+1

@AlexCppns
Copy link

Is it too late for me to add a +1 ?

@sisidovski
Copy link

+1

@obiddle
Copy link

obiddle commented Mar 13, 2015

+2 critical for cross-platform spas

@laslorma
Copy link

this seems to be a solution for this issue : http://www.yearofmoo.com/2012/10/more-angularjs-magic-to-supercharge-your-webapp.html

@mntnoe
Copy link

mntnoe commented Mar 31, 2015

+1

8 similar comments
@mathewbergt
Copy link

+1

@nicolae-olariu
Copy link

+1

@YonathanB
Copy link

+1

@pedrolopix
Copy link

+1

@EwanValentine
Copy link

+1

@Morriz
Copy link

Morriz commented Jul 23, 2015

+1

@aarongray
Copy link

+1

@ghost
Copy link

ghost commented Aug 3, 2015

+1

@mntnoe
Copy link

mntnoe commented Aug 3, 2015

I made a gist containing a quick edit of my approach to support resolves in directives:

https://gist.github.com/mntnoe/56ad60b11549a877d4cc

Hope it may give some inspiration on how resolves could indirectly be supported by using a wrapper function around the directive definition object.

@hiddenboox
Copy link

+1

4 similar comments
@fijimunkii
Copy link

+1

@mikepc
Copy link

mikepc commented Aug 25, 2015

+1

@vitaliyshvarz
Copy link

+1

@dwilt
Copy link

dwilt commented Sep 8, 2015

+1

@dgreene1
Copy link

+1

Why not have it as an option, right?

@carlos-algms
Copy link

+1

@bogini
Copy link

bogini commented Sep 21, 2015

+1

2 similar comments
@rflmyk
Copy link

rflmyk commented Sep 22, 2015

+1

@xmakina
Copy link

xmakina commented Sep 23, 2015

+1

@ksgupta
Copy link

ksgupta commented Sep 23, 2015

+1

@AlexCppns I had the same question when I browsed to this topi; but seems it is not.

@lukaszwado
Copy link

+1

1 similar comment
@elerman
Copy link

elerman commented Sep 23, 2015

+1

@btford
Copy link
Contributor

btford commented Sep 23, 2015

There are several ways to achieve this that others have mentioned in this thread. As @caitp noted, there's not a great way to implement this without greatly increasing the already complex Angular 1 compiler.

The good news is that Angular 2 supports this (and much more) at the DI layer in a way that's cohesive and doesn't introduce a ton of additional complexity.

I'm going to lock this thread, but thank you all for your interest and feedback!

@angular angular locked and limited conversation to collaborators Sep 23, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests