0

Is the following a roughly correct description of how Angular 1.x works?

AngularJS places an object angular on the global object.

This angular instance can be configured using syntax like:

angular.module('my-module', []).directive('myDirective', myDirective);

An angular application can be created using angular.bootstrap to create "application 1":

angular.bootstrap(domNode, ['my-module']);

If I then re-configure the angular object:

angular.module('my-module').directive('myDirective', myDirective2);

...then "application 1" will not see this configuration change.

But if I use bootstrap a second time (on another DOM node) to create "application 2":

angular.bootstrap(domNode2, ['my-module']);

...then "application 2" will see the change (and will not see the original myDirective), and "application 1" will remain unaffected.

Ben Aston
  • 53,718
  • 65
  • 205
  • 331
  • 1
    Yes, this is how it works. – Estus Flask Oct 28 '16 at 15:02
  • 1
    You might want to test this to see if it behaves how you want. Your second call to `directive` will add a second definition for 'myDirective' so the second application will have both (you can have two directives with the same name). The second call to `bootstrap` will create a second injector, so the first application will not be affected, but the second application will have two definitions for 'myDirective'. – Jack A. Oct 28 '16 at 16:31
  • Are you sure you can have two directives with the same name? How could they be told apart if that were true? – Ben Aston Oct 28 '16 at 16:35
  • What is the point of running more than one angular application on a single page? Even more so, what is the point of trying to "trick" the bootstrapper into allowing it by doing it in this manner? All you end up doing here is creating unnecessary spaghetti code. – Claies Oct 28 '16 at 17:29
  • @BenAston Yes, there can be two directives. If there's more than one directive with same selector and priority, they will be executed in the order of their registration. – Estus Flask Oct 28 '16 at 18:00
  • 1
    The order in which they are evaluated depends on the priority. When the priority is the same, my simple test ( https://jsfiddle.net/o22bxnbf/1/ ) indicates that they are evaluated in reverse order of registration (last registered is first evaluated). – Jack A. Oct 28 '16 at 18:24
  • @estus please can you confirm the "and will not see the original myDirective" in the final line of my question? This is the behaviour I have observed but is at odds with Jack A's comment. – Ben Aston Oct 28 '16 at 22:36
  • @JackA. This is the order for postlink functions, they always run in reverse. Directives themselves run in the order of registration. – Estus Flask Oct 28 '16 at 23:01
  • Yes, that's a part that needs some explanation. If both directives have templates or controllers, this will cause an error, always check the console. If you have some example to replicate the opposite behaviour, feel free to add it to the question. Glad you've checked [the answer](http://stackoverflow.com/a/31703559/3731501), it is closely related to the subject. – Estus Flask Oct 28 '16 at 23:08
  • @estus Yes, I'm referring to the order in which the postlink functions are evaluated because typically the code in which they perform the operations that actually have an effect on the application. Could you clarify what you mean by "run" if you're not referring to the postlink? – Jack A. Oct 29 '16 at 01:27
  • @JackA. More precisely, compile, controller and pre-link. – Estus Flask Oct 29 '16 at 03:30
  • @estus Priority affects compile, prelink, and postlink. From the docs ( https://docs.angularjs.org/api/ng/service/$compile#-priority- ): "Directives with greater numerical priority are compiled first. Pre-link functions are also run in priority order, but post-link functions are run in reverse order." – Jack A. Oct 29 '16 at 04:16
  • @estus I have created a fiddle (https://jsfiddle.net/o22bxnbf/5/) and as long as the module is different I don't get a conflict with the directive. What are the problems with this approach? – Ben Aston Oct 29 '16 at 10:57
  • You won't get a conflict. Just because they are 2 different modules that don't know of each other's existence (at least at the moment of bootstrapping). There is only 1 module in the question ('my-module'), and everything that was said above is applicable to the case when there is 1 module. Is it a real-world issue? Because nested Angular apps are absolute no-no. It is somewhat acceptable to have them in sibling elements, but there is rarely a good reason to do this, too. – Estus Flask Oct 29 '16 at 14:10
  • @estus OK thank you. Yes this is a real-world issue. What are the reasons nested angular apps are an absolute no-no? – Ben Aston Oct 29 '16 at 15:11
  • ...I ask because I know of one production implementation where they nested Angular applications without issue (I can only go on what I was told in this case). – Ben Aston Oct 29 '16 at 15:19
  • Because it is a nasty hack for the use case that Angular wasn't developed for. The framework has foolproof system to prevent this but it was bypassed in this case. The problem is that apps may interfere on some conditions. I've had some experience with multiple Angular apps and can say that there are virtually no valid reasons to abuse the framework this way (the exception would be some kind of app construction set or so). If a dev has to fight the framework, this means that he/she does it the wrong way. Check also [this answer](http://stackoverflow.com/a/32955398/3731501) for some details. – Estus Flask Oct 29 '16 at 15:48
  • This is for an app construction set. I understand this is a nasty hack and that Angular was never intended to be used this way. If I follow the nested app approach it will be in the knowledge that this will be an abuse of the framework until the organisation moves to more modern tech like Angular2 and library-based functionality. I would love to hear of any pitfalls you have found in your experience of nested apps. – Ben Aston Oct 29 '16 at 17:05
  • 1
    If you're ok with the fact that this trick may void your warranty, that's good (because it will). The method you're using here (bootstrapping detached DOM) is quite dirty but it allows to bootstrap it safely, so core Angular code may be fine with it. But third-party code, especially jQuery directives will be pissed off with that (shadow DOM would be cleaner but has the same issue). If parent app will happen to recompile hosting element (with transcluding directives for ex.), it will screw up everything. Iframe is probably the safest alternative. – Estus Flask Oct 29 '16 at 22:15
  • Thank you. I asked a more specific question on this here: http://stackoverflow.com/questions/40323921/nested-and-sibling-angular-applications-in-angular-1-x?noredirect=1#comment67903723_40323921 – Ben Aston Oct 29 '16 at 22:21

0 Answers0