Loading controller from partial - angularjs

I would to dynamically load controller in my partial file so my code is better organized. Through my research, I found that if I want to load controller from partial using the script tag, I need to include JQuery.
However, these approach seem to only work if my controller is declared in the global scope, i.e.
function MainCtrl($scope) {}
If I switch to using module in my controller.js
angular.module ("myApp").controller ("MainCtrl", function ($scope) {});
this no longer work with the error message
"Argument 'MainCtrl' is not a function, got undefined"
Below is a plunker to demonstrate this.
http://plnkr.co/wNv3UD
How could I make this work?
Note
I did not include controller.js in index.html intentionally. I want to load controller from the partial.html, since it would only be used there.
Edit
I was able to achieve what I wanted to to after reading this question: AngularJS Dynamic loading a controller
This seem to be a straightforward approach to support lazy loading. Hopefully the $controllerProvider.register method could be exposed through angular.module.controller in future versions to support lazy loading.

You may want to take a look at [RequireJS][1]
it provides a good and easy way for you to load your .js files on the run.
for the dynamic controller loading part: you should write a provider (a service) which exposes some methods to register your controllers wile the angular app is running (take a look at $controllerProvider in angular docs)
i suggest you take a look at this post as it mentions how to fully customize your application regarding the script loading and controller registeration and stuff like that.

You can achieve this using custom directive and in directive you can load script using jquery getscript or jQuery ajax call, directive will fire when you load the partial

Related

load only controller files on demand while routing Angularjs and requirejs

I know this question maybe duplicate.But I am still not getting valid results based on those answers.Anyways i have following doubt:
I want to implement angularjs with loading controller files on demand, with template routing.I have used requirejs concept for this.But I am not able to load ONLY controller files on demand.
For ex.
app.config(function($routeProvider) {
$routeProvider.when('/', {
controller:'page1',//I want to load controller file here
templateUrl:'page1.html'
});
});
I have used resolve concept here,but it didn't helped.
In above code I want to load controller file and also bind it to respective view.Please provide any solution or reference.If possible please provide detailed solution.
Thanks.

Registering AngularJS components via providers

I'm implementing an Angular/RequireJS routing solution based on Dan Wahlin's article.
In the article, Dan makes the following register shortcuts on his app object:
app.register =
{
controller: $controllerProvider.register,
directive: $compileProvider.directive,
filter: $filterProvider.register,
factory: $provide.factory,
service: $provide.service
};
When I use these, I can correctly register and reference my controllers through RequireJS calls, but if I use the traditionall app.controller() or angular.module('myApp').controller() syntax, then Angular can't find them and I get errors from the router.
How is defining controllers, directives, etc. with the above method different, and why does it work with RequireJS where the more traditional method does not?
Any ideas?
Thanks,
-Nate
Since the controllers are being added dynamically things have to change a bit from the "norm" (unfortunately). The main difference is that controllers are being wrapped in RequireJS modules, being downloaded dynamically, and then being registered. The $controllerProvider.register allows for the dynamic registration. It's definitely not the normal technique but what's required in this scenario. That's why "app" (which is the RequireJS module that gets us to the application's AngularJS module) is passed in to all of the controller modules. It exposes the controller property shown above which handles the registration "on the fly".
If you download a controller script dynamically and then use the normal technique (angular.module('..').controller(..)) it won't register it properly - at least that was the case the last time I tried it. It's been several months since I've tried it but I'm assuming the same behavior is still there.
The bottom line is that when controllers (and other items such as services/factories) have scripts that are loaded "on the fly" things change somewhat and the way you access and register these items changes from the normal way that we're all used to seeing.

Refresh a controller from another Controller ~ Angularjs

Is there a way to refresh a controller from another controller?
For example, Controller1 runs then Controller2 runs. At the end of Controller2 there is a
"command" to re-run Controller1. Is this possible?
In my post I had made earlier it seems like my questions was unclear what I was trying to do. Here is a link to it.
Updating a controller from another controller Angular
if you are using ngRoute there is a method to re-run the all the controller without having to reload the page.
app.controller('MyCtrl', function($route){
$route.reload()
})
If you want to refresh data, please use services and refresh data in the services. Sequential things can be done of ajax by using promises. Please let me know if you need any help in designing the solution
I think you need to look into using directives. By using directives you can encapsulate and share scope objects.
Please read the documentation on directives and "shared scope".
http://docs.angularjs.org/guide/directive

how to load angularjs and my models at the correct time

I am struggling to find a way to get angular and my code to play nicely and since angular is awesome i know it must be my problem.
Some of my models have static data only but most have either only dynamic data that i pull in from rest services or a combination of static/rest data.
many of the examples i see here and in the docs just deal with a small static json set of data.
My problem when i put the angular script call in the html it tries to load and execute before my models are loaded and ready to go. there has to be a way to coordinate that loading time.
So i have tried to devise ways to make sure my model js scripts are all loaded and then finally call for the angular script in a getScript call.
Also i wrote a custom filter and i want that to be added to my module. when i add the module name to the ng-app tag and i try to lazy load the angular script via getScript it errors and says it doesn't recognize my module name.
If i remove the module name from ng-app and then try to initialize my filter module it does lazy load angular.js but then it says my filter method is invalid because (i guess) it is not registered with the model.
I'm sure i'm missing some key piece of information somewhere. Angular has to be smart enough to load and then realize that my models will take a few moments to arrive. Not just run through my html and bark at the first ng-controller tag because the model isn't loaded or the service call to fill the model is not done yet.
Right now if i put a tag on my html like so:
<html class="no-js" ng-app="yourApp">
I get an error when i call getScript on angular.js that says
angular.js failed to load: Error: No module: yourApp
Please help. thanks for any suggestions.
If I understand correctly, you load angularjs not during page load, but via an ajax call? If you do that you will need to do a manual bootstrap.
Here is an example I'm using with require.js, but with jquery's $.getScript(), it will be similar:
require(['angular', 'jquery', 'app/app-config'], function (angular) {
'use strict';
angular.element(document).ready(function () {
angular.bootstrap(document, ['app']);
});
});
In your case it will be something like:
$.getScript("http://code.angularjs.org/1.0.4/angular.js", function(data, textStatus, jqxhr) {
angular.bootstrap(document, ['myApp']);
});
Just make sure all javascript files with controllers, directives, ... are loaded too.

Lazy-load external JavaScript in one of AngularJS controller

Some of my routes needs functionality from external JS. I don't want to load them all at once since those JS are needed only in certain routes (e.g. /upload needs some JS for photo uploading, /photos needs another JS for lightbox, /funny needs JS for animation stuff, etc).
What's the best practice for lazily loading those external JavaScripts?
Those routes can be accessed multiple times (e.g. user can go to /upload then /photos then /upload again)
In addition to what Alex has stated, if you will be lazy loading AngularJS artefacts such as controllers and directives, you would have to use the relevant provider to register them instead of the module API. Artefacts registered using the module API after the application has been bootstrapped, will not be available to the application. For example, you would define a lazy controller like this...
$controllerProvider.register('SomeLazyController', function($scope)
{
$scope.key = '...';
});
instead of this...
angular.module('app').controller('SomeLazyController', function($scope)
{
$scope.key = '...';
});
I have written a blog post detailing this as well as how to use the 'resolve' method that Alex speaks about, to implement lazy loading in AngularJS. http://ify.io/lazy-loading-in-angularjs/
The only way I know to handle cases like this is using the "resolve" method of a route. This method can be used to define a dependency to be loaded before the route's controller is instantiated. One of the different possible return types of this method is a promise. Thus you might use this to start loading your external JavaScript code asynchronously and return a promise that is resolved as soon as your external scripts are loaded.
The documentation for this can be found here: https://docs.angularjs.org/api/ngRoute/provider/$routeProvider in the "when" section.
#alex3683's answer is probably the correct AngularJS way, but I don't grasp the concept, so instead I make use of jQuery's getScript(). So, in CoffeeScript:
yourModule.factory 'foo', ->
$.getScript 'https://script-to-load', ->
# whatever you want to do once the script is loaded
And just call it from your controller. Since AngularJS services are lazy and singleton, this will only load the script once.

Resources