How can I execute Angular code without bootstrapping? - javascript

All manual bootstrapping examples use the following pattern:
angular.module('myApp', []);
angular.bootstrap(document, ['myApp']);
However, I don't need angular to look at the document, I just need to open a popup using ui-bootstrap module.
The best I managed to do was the following:
$("...").click(function() {
angular.module("pp", ["ui.bootstrap"])
.config(["$modal", function($modal) {
$modal.open({
template: "Hello!"
});
}]);
angular.bootstrap(null, ["pp"]);
});
However, that will re-bootstrap angular every time, re-create the same module over and over, and above all that it doesn't work - configs run alongside provider initialization, thus there is no $module dependency available at that time.
Basically, I am trying to incorporate angular into existing application without creating significant disturbance in current structure. I want angular to manage a single popup, nothing else for now, so normal bootstrap & controller way doesn't seem to be the best option.
Is there some way to run that modal without doing global angular bootstrap?

Have you tried bootstrapping angular to the whole document and simply not using it for anything but the modal call? Unless there are namespace conflicts with your current code, it seems like this would allow you to use Angular functions wherever you please without bootstrapping every time.

Why not use just Bootstrap without the angular wrapper?
The angular directives only wrap the original bootstrap modals with some extra stuff.
Seems to me a bit pointless to include Angular + Bootstrap + UI Bootstrap when you can achieve the same just with Bootstrap itself.

Related

Implement a logical part as Generic one in AngularsJs

I have recently started working on ANGULARJS in which I was encountered a case where I need some guidance to go through. Am implementing a message section in my application(ASP NET MVC - ANGULARJS).Currently I have implemented the message section for a specific module under a particular ng-app and under particular ng-controller. Now I need the same functionality to be used inside another module. It's like duplicating the same code again that ng-app under that ng-controller which was not a good approach. I just wanted like and plug and play kind of approach for my ANGULARJS code.
I have used 2 service,1 directive under that particular ng-app and some functions inside a particular controller. All I want is to make these one a common code and to be used inside under any ng-app and ng-controller.
Is this possible? If so how can I achieve.
Let me know if the query was unclear
You said you used 2 service, 1 directive, and controller etc for your messaging feature. If you want to re-use it across various applications, you need to bundle all of this as a module. for example:
angular.module('customMessaging', [])
.controller('messagingCtrl', function(messenger, messageManager) {
....
})
.directive('messagingDir', function() {
return {
controller: 'messagingCtrl'
...
}
})
.service('messenger', function() {
...
})
.service('messageManager', function() {
...
})
Now you can specify this as a dependency of any of your angular applications as shown below to access the directive, services and controller anywhere in the app:
angular.module('myfirstApp', ['customMessaging']);
angular.module('mySecondApp', ['customMessaging']);
Thanks for the suggestions. I have moved the message related functions such as services, directive and controller related functions into separate JavaScript file . And invoked this JavaScript file where I need message related functionalities.
Let us say that JS as Message.JS . In Message.JS I have used the app variable(Instantiated app from the JS Specific to the page globally).
JS specific to that page
var app = angular.module('appname',[]);
app.controller(...)
Message.JS
I have used the same app in my message.JS since message controller falls under that app.
app.service(...)
app.controller('messagecontroller',[]...)
When ever I need to invoke a function inside MessageController I will use Broadcast in angular to achieve this.For more info http://www.dotnet-tricks.com/Tutorial/angularjs/HM0L291214-Understanding-$emit,-$broadcast-and-$on-in-AngularJS.html
Regards,
Selvam.M

Using Angular Dragula without RequireJS

I would love to implement Drag and Drop in my Angular project using the angular-dragula module (https://github.com/bevacqua/angular-dragula). However, it seems to be heavily dependent on RequireJS. I've not used Require for a while and only then for an example app or two. Is there an easy way to untangle Require from this module?
The author seems to think it is simple (https://github.com/bevacqua/angular-dragula/issues/23) and has shut down similar questions as well without a real explanation. I've looked at the code and don't see how to load the module without adding RequireJS to my project (which I don't want to do). Am I stuck with either not using this module or adding Require or is there a way to use this without Require?
OK, after help from those who commented (thanks everyone!), I was able to get this to work. There are a couple things that you need to do. First, I was bundling this module with the rest of my modules and trying to call it. That will not work because it needs to initialize with a parameter (angular). Therefore, you need to do the following:
Add a reference to angular-dragula.js (or the min version) to your index.html page below the declaration for angular but above where you create your app.
When you declare the dependencies for your app, specify angularDragula(angular) (not in quotes).
Use dragula as you normally would. If you need to access the service, the name would be angularDragula.
For example, here is my declaration of app:
var app = angular.module('app', [
'ngRoute',
angularDragula(angular)
]);
And then to get a simple list to be drag and drop capable, this is my html:
<div dragula='"bag-one"' dragula-model="vm.items">
<div ng-repeat="item in vm.items">{{ item }}</div>
</div>
Note that I do not declare angularDragula anywhere, unlike the examples. In the example the author gives, he requires angular and creates the angular variable and then he requires angular-dragula and creates the angularDragula variable. This is not needed if you are not using RequireJS as long as you load the scripts in the right order.

Correct paradigm for mixing angular code with external code

Angular Newbie here. I'm trying to understand the paradigm to use when developing an Angular app so I can use external libraries while keeping the Angular app reusable.
So imagine I've got a form that uses ng-submit:
<form ng-submit="submit()">...<!--code goes here --></form>
And then inside the corresponding ng-app and ng-controller (assume those are declared in a parent element), I've got my submit function. But say, on this page only, I want to use a custom alert library after submitting:
$scope.submit = function(){
// code goes here to submit form data
//now tell the user that save was successful
customAlertLibrary.alert("your data has been saved")
}
Now that's not reusable code, is it? I may want to reuse this ng-app on another page to modify and submit data, but don't want to use the custom alert library. It seems like you're trapped because the ng-submit attribute restricts you to functions inside the corresponding ng-app, not external functions. So what is the correct way to invoke other Javascript code alongside my Angular code without baking it into the model?
This question is very similar to this question about making lodash available in templates. There are many ways of adding external (or in-app) code or data-structures to your Angular scope. I prefer to add special-purpose stuff to each scope individually, and general-purpose utilities (such as lodash or momentjs) globally:
app
.run(['$rootScope', function($rootScope) {
$rootScope._ = _;
$rootScope.moment= moment;
// or:
// $rootScope.util = {
// _: _,
// moment: moment
// };
});
If customAlertLibrary isn't crucial to your app, I'd say do something like this
$scope.submit = function(){
// code goes here to submit form data
//now tell the user that save was successful
if ($window.customAlertLibrary) {
customAlertLibrary.alert("your data has been saved");
}
}
Otherwise, I'd suggest using Bower to manage dependencies. You install packages with Bower, and your own app can be a package that gets included and installed by other apps. Any dependency your app has gets installed as well (the user still has to include it on their own end in a <script> tag)

Angular inside of Angular - solving: WARNING: Tried to load angular more than once

I have a small angular app that just has one directive.
It will be used on many other websites, simply by them including one JS file and then using the directive anywhere on their page.
The problem is that if I try to do this on a site that happens to also use angular, I get the classic
WARNING: Tried to load angular more than once.
This is because angular loads itself on the global namespace.
I have tried messing with the angular.js code, doing find-and-replace on instances of things like:
angular = window.angular || (window.angular = {})
to
angular = window.angularXYZ || (window.angular = {})
But it didn't work and it seems very hacky.
Any ideas for namespacing an entire angular app so that it can play nicely when initialized from within other angular apps?
A crazy but also the most realistic solution would be to load your code in an iframe.
I think the variable you're using may be incorrect, at least according to this blog post:
if (window.angular.bootstrap) {
// already loaded
} else {
// magic: somehow namespace the angular app!
}
I know it might be a pain, but if angular is already loading on one site, I would suggest you log the version of angularjs it's using and test your code against it. Otherwise you're loading up a relatively heavy framework twice.
Obviously if there's lots of versions of angularjs being used, you should only test against the most common version and the version you're currently using and suggest to the client to upgrade their version of angularjs.
what you can do is.
if (typeof angular === 'undefined') {
document.write('<script type="text/javascript" src=""angular.min.js""></script>');
}
this way angular would be loaded only if its not defined already...

Custom directives on AngularJS pages without specific ng-app module set

I have some simple pages that don't need a specific application module to be provided in the ng-app attribute. But those pages also use some of my custom directives.
As it seems natural I've put all my directives in separate namespace (namely module) i.e. MyApp.Directives.
This is all great when I also provide my application module, because I add MyApp.Directives as dependency and it works.
angular.module("MyApp", ["MyApp.Directives", ...])
But. As said I also have some very simple pages, that don't really require any particular application module because they don't need any custom controllers or anything. They're just driven by ng-... attributes/directives.
Question
I know I can simply add all my custom directives to ng module and they will become accessible to all pages. Those with custom application module and those without. But this beats the purpose of modules, so I'm wondering if there's any other way to tell dependency injector of my additional directives/filters?
I would like to avoid any unneeded code in my application to keep is small and maintainable. (what AngularJS is all about). What I'm looking is actually some sort of hack that I'd be using in my directives' files to make ng module aware of my directives but without adding them to ng module directly... A rather advanced Angular question as it likely involves some internals manipulation.
I've tried manully adding my directives' module to angular.module("ng").requires array but that didn't do the trick.
#1) If you only have one module you can do it with ngApp:
<html ng-app="MyApp.Directives">
#2) If you have multiple modules you can use angular.bootstrap like so:
angular.element(document).ready(function(){
angular.bootstrap(document,['MyApp.Directives','MyApp.Filters']);
});
#3) Or just create a simple module for declaring dependencies:
<html ng-app="myApp">
......
<script>
angular.module('myApp',['MyApp.Directives','MyApp.Filters']);
</script>
If we could only write something like this:
<html ng-app="MyApp.Directives MyApp.Filters">
I made a patch to the source code:
function angularInit(element, bootstrap) {
// some code
if (appElement) {
bootstrap(appElement, module ? module.split(/\s+/) : []); // split by spaces :)
}
}
Here is a demo: http://plnkr.co/edit/kSrY3WYzLG39NJ4UgTRM?p=preview

Categories

Resources