I'm trying to integrate angularjs with dojo.
I've decided to wrap creation of dojo objects in an external module, in order to leave my controller clean.
So I have a factory that exposes creation of an AndOrReadStore instance, for example, and then in the controller I use it to instantiate my dojo store.
Here is an example of what I'm trying to do:
http://plnkr.co/edit/EM0kXKWqZzZrlISvsOik
The problem is that the assignment to the store in the controller occurs before the code inside the requirejs block gets executed (and it doesn't make any difference if the async property of dojoConfig is true or false).
How can I use a factory method that is asynchronously? Could premise solve my problem?
Thanks,
Lior
Related
I'm using AngularJS with material. I'm in the process of creating a re-usable dialog. I tried to make it as a directive but looks like it's not possible because we've to manually call $mdDialog.show/hide methods. I'm confused whether I've to use a factory or provider in this case?
Given the code:
angular
.module('someApp', ['provider1Module, provider2Module'])
.config(function (provider1ModuleProvider, provider2ModuleProvider){
provider1ModuleProvider.getSomethingSpecific()
})
Given also that provider1ModuleProvider.getSomethingSpecific() depends on a method of provider2ModuleProvider's getSomethingGeneric() method, how can I call this method from within the config?
Right now, when I try to run code similar to this, I get an error that essentially tells me the second provider is not instantiated. Can I explicitly instantiate both providers in the config in some way so that one provider's dependency on the other is resolved?
Essentially, what I'm trying to do is get some data in an abstract view state for some views in UI-router so that I can use it in child views. If my pattern above won't work, any other suggestions?
Can I use databinding for dependency injection? I'd like to pass the services I want to call on the JSON file being delivered to the AngularJS application.
app.directive('directiveName', ['{{ Data.servName }}','lookupService', function () {};])
Can I use databinding in this method?
No, and that sounds like a terrible idea. Your REST api shouldn't be tightly coupled like this to your angular client implementation.
Anyway, if you has the name of a service and want to get this service instance, inject the $injector service, and call its get() method with the service name as argument.
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
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.