AngularJS and modularisation - angularjs

AngularJs provides you the possibility to create modules. All fine. It also give you the power to add components to your modules like service, controller, etc...
My only problem with that is that no matter in what module did you define a component, from another module it can be entirely overwritten.
Examples:
app.module('aModule').controller('SimpleController', functino(){...});
app.module('bModule').controller('SimpleController', functino(){...});
If you try to define let's say a state definiction with ui-router, it will just won't work well, since one controller will completely overwrite the one loaded first.
Did you guys met with this problem too or it's just me?

no, that's normal behavior. You can namespace it like 'component.controller' (so do this in the name of the controller, not the module) which helps, other then that is not possible in Angular 1

Related

Access an Angular scope variable outside of Angular

I need help please, and thank you in advance: I have two Javascript files A.js and B.js. A is written in Angular and B is not. Now B needs to change a value of a scope variable inside A's controller. How can I do that? Thank you.
If you are using angular in the project already and the angular library is available, you can access the scope assosiated with any particular DOM element using angular.element().scope()
So, determine which DOM element is associated with the scope that you need, then use something like angular.element(document.getElementById('elementId')).scope(). From that you can access the scope variables.
Be warned though, if you change a variable this way and want the changes to be seen by your angular app, you'd probably need to add a watcher.
It's simple, in your A.js :
window.myVar= $scope.angularVariable;

Me, AngularJS, and its 3 different ways to specify a controller

I'm confused by these three different ways to specify a controller.
1- I can have an include in the app/index.html file:
<script src="scripts/controller/nav.js"></script>
2- I can have an attribute in a route:
.when('/link/list/', {
templateUrl: 'view/list.html',
controller: 'navController'
})
3- I can have an attribute in a view:
ng-controller="navController"
It's quite a few. I wonder which way to go and when.
Kind Regards,
Stephane Eybert
Your (1) has nothing to do with (2) and (3).
And there are other places where you can bind controllers (e.g. a directive's controller property).
Each way is serves a different purpose, so go with the one that suits your situation.
If you have a directive and want to give it a specific controller, use the Directive Definition Object's controller property.
If you use ngView and want to give each view a specific controller (as is usually the case) use the $routeProviders controller.
If you want to assign a controller to some part of your view (in the main file or in a view or partial) use ngController.
All the above are methods for "binding" a controller to some part of the view (be it a single element or the whole HTML page or anything in between).
Im quite new too but Ill try to explain in a more layman way.
1 For each .js file you have (which may contain one or more controller defined), you need a corresponding entry into the script for #1 there. Its not the controller itself, more like to allow script to recognise that this .js file is part of the set of files to run.
2 is more like specify a state or route, which may or may not use a controller. Its much like saying how one event should lead to another. The controller may be involved in the transitions of the states/routes (ie. responsible from one state, to another) or within a view itself.
3 is for using a controller's functions within a view itself.
I've added comments to one of the answers, but aside from syntax this may is more of a design question. Here is my opinion
Firstly, (1) is irrelevant to the conversation.
(2) is the preferred approach when specifying the controller for the view as it decouples the controller from the view itself. This can be useful when you want to re-use the same view by providing a different controller.
If you find yourself using (3),consider making that area into a directive, since by specifying a controller you are indicating that it requires its own logic.

What is the correct way to extend an AngularStrap directive?

I'm looking to extend an AngularStrap directive (typeahead in this case) to have more than the provided functionality. After some research, I'm thinking the best way is to wrap the typeahead directive with my own custom directive so that I can extend it.
I've followed all 3 suggestions found here for extending an Angular directive, but none of them seem to give me access to the typeahead controller and it's public functions.
Am I going about this the wrong way? What is the best way to extend the directives for custom functionality? Any help is greatly appreciated.
In my case, I followed the approach similar to the 2nd way described there.
The difference was to use 'require' to refer to the controller of the parent directive.
How to require a controller in an angularjs directive
If you look at the source of AngularStraps typeahead directive (Link) you'll see that it has two parts, the provider; '$typeahead' and the directive 'bsTypeahead'. What I've found in the past is easiest with this library is to copy the 'bsTypeahead' directive, rename it to something else then modify it's code to do as I want. The $typeahead provider acts like the controller in this case and all other AngularStrap directives work the same.
First, the best way is definitely to wrap the Angular Strap Directive in a Directive of your own. I've done this quite a bit with different Strap Directives. Secondly it's hard to say specifically what you need to do because you didn't name any specific goals. But if you look on the doc's for the Angular Strap project you'll notice various hints. In the case of typahead you have access to the $typeaheadProvider, also this is some what speculative on my part, but typeahead has a tooltip dependency so you may be able to use the $tooltip service to fiddle with typahead in your wrapper. Finally, the Angular Strap API for typeahead is pretty robust take another look at what is already available and you maybe able to accomplish what you want/need by working with what you've already got. I.E you can specify a custom template, or specify different prefix events which after taking another look at the docs myself seems to be an interface for interacting with the tooltip scope methods. I'm sorry this couldn't be more detailed on exactly what you need to do, but hopefully it will get you moving in the right direction.

AngularJS - How to route to a controller in different module

I have a question related to modules and routing in angularjs. The requirements are to define all routing configs in one module - lets call this ModuleRtr.
Once the route is triggered, it should call a controller (called TestCtr for example). This controller is defined in another module - let's call it ModuleCtrl.
If I try to do that, I got an exception like:
"Argument TestCtr is not a function, got undefined"
. The reason is that when angular broadcast $routeChangeSuccess event, the listener tries to access the controller (TestCtr) as part of the current module - ModuleRtr. Because it's not there, it throws an error.
If I simply create TestCtr controller in ModuleRtr (the same that has the route in it), then everything works. But I don't want that, I want to have my TestCtr in different module. I also don't want to have route define in ModuleCtrl module.
So, in more straightforward way, my question is: Is it possible a route defined in one module (ModuleRtr) to call a controller defined in another module (ModuleCtrl)?
Something that I forgot to mention...I don't want to bind these 2 modules by any means. That of course includes listing a dependency during module's creation. I have already tried dynamic loading of TestCtr - it didn't solve the problem.
The scenario is: You have 2 angularjs applications (modules). They don't know anything about each other...except one thing - somewhere in a shared/common location, there is an object which follows a particular structure (like a contract). The first module writes data there. Then it runs a common function from the second module (this is actually the question I am asking - how?). Then the second module knows already where to go (it's a contract) what to read and what to do. One way I can do this is to try dynamically generates the string that represents a module dependency when the other module is created. I am not sure if that is a good solution...
Many thanks!
You can use a single module with submodules for each functionality, such as:
angular.module('myApp.home',[]);
angular.module('myApp.routing',[]);
...modules here...
angular.module('myApp', [
'myApp.home',
'myApp.routing'
]);
So you can send a method from myApp.home calling a intermediate method from myApp and this one calling the myApp.routing method.
At least, this is how I see it.

Extending directives in AngularJS (sharing properties before and after link)

I have a directive which creates a rich text editor in its LinkingFunction. The small directive I'm using for my rich text editor can be found at https://github.com/angular-ui/ui-tinymce/blob/master/src/tinymce.js.
I need to extend this directive with another directive which will allow me to configure the default options and access the element created by the previous directive.
If possible, I would like to do this without forking the original ui-tinymce directive (linked to above). In this directive there are two properties:
uiTinymceConfig which I need to be able to access and configure before this directive's LinkingFunction is run (before the options are passed to TinyMCE)
tinyInstance which I need to manipulate after it has been created by this directive
I've done plenty of research into extending directives, as well as the different attributes available to the "Directive Definition Object", such as link, pre-link, post-link, compile, and controller. I have experimented with sharing properties between two directives using some of these methods, but I have not come up with a solution that fits my needs (above).
I am happy to fork this original directive code if it is not possible to achieve what is needed without doing so.
So I investigated this a little for you, and came up with this Plnkr.
This will let you override the value provided for injection - note that you can do this in a module that depends on the submodule, so you can provide different configurations for different modules that depend on the submodule, which would be of use for the ui-tinymce directive.
Using a similar principle, you should be able to edit the config value for uiTinymceConfig by just simply overriding it. You can even do this and override it right in the base module if you'd like.
If you want to edit the instance itself after instantiation, you can simply access it by using the ID attribute and calling tinymce.get('#IDattribute') directly anywhere in your code.

Resources