Trying to learn backbone. In several applications that I've looked at (here is one http://blog.viison.com/post/11097185009/how-to-switch-views-using-backbonejs ), the author of the app or demo app initializes the ApplicationRouter in the index.html file, while all of the other javascript is in a JavaScript folder. What is it about the application router that makes it necessary to initialize in an html file?
<script type="text/javascript">
var router = new ApplicationRouter($('#content'));
Backbone.history.start();
</script>
There's no requirement to do it inside the html. The author could be doing it there for ease of illustration. You could ask... the author has comments enabled on the blog post.
I've not seen it initiated in the html too often. Something like Backbone Boilerplate would be a good example of not initializing the router in the html.
https://github.com/tbranyen/backbone-boilerplate
Related
quick question, kinda dumb. Let's say you have your web app with an index.html and app.js where you want to place all your angularjs modules. Does the app.js need to be located to the same place the angular library is?
Or it doesn't actually matter since you will be loading both angularjs and your app.js at the index.html?
app.js would contain something like:
var app = angular.module("myApp", []);
Is the message var app undefined just a matter of letting js know that this var is a global var?
It doesn't matter. You just include the correct script source paths in the script tags.
I am working with an existing application that I would like to add angular to. The application is using a custom proprietary SPA framework + dojo. The application is built with mainly dojo modules and heavily utilizes AMD modules.
I have imported angular in the head with
<script type="text/javascript" src="lib/angular/angular.js"></script>
I have also added
<html ng-app="myApp">
<script>
angular.module('myApp', [])
</script>
to my index.html.
I have also tried manually bootstrapping via
var app = angular.module('myApp', []);
angular.element(document).ready(function() {
angular.bootstrap(document, ['myApp']);
});
but still
{{1+1}}
Does not evaluate. It remains as {{1+1}}
The only way I get get it to (sort of) work is in my partial view (rendered inside body of index.html) and I manually bootstrap the application via
var app = angular.module('myApp', []);
angular.element(document).ready(function() {
angular.bootstrap(document, ['myApp']);
});
But as soon as I leave the page and come back, the bootstrapping is gone. {{1+1}} shows as {{1+1}} not 2. If I run the above code again, I get an error saying document is already bootstrapped.
No errors are thrown in console..
I am not sure what to try next. Any help? Thanks
Is the page content dynamic, are the other frameworks adding HTML to the page that has Angular syntax in then you are expecting to be evaluated? If so that is the issue.
Please note that Angular is a fully featured framework and that frameworks generally conflict with each other. For Angular to work you need to add Angular code to the page using Angular APIs, such as ng-include, other directives, or a controller and manually compile the HTML being added.
When is the partial view actually rendered?
Unless you actually pass the partial through Angular's $parse service (which happens automatically on bootstrap), Angular can't evaluate the expressions. So, if you are adding the partial to the DOM after the bootstrap, Angular will never process it.
using dojo, you would need to pass the content through the $parse service first, i.e.:
require(["dojo/html"], function(){
content = $parse(someAngularContent);
html.set(node, content);
});
Is there a way to make the AngularJS partial views a complete HTML files, so they will be easier to edit
and have Angular strip them to their body content (much like what the RequireJS text plugin does with the strip option)
I will clarify my question since the answer and comments show that it was not clear enough:
currently the content of the partial file is:
<p>{{value}}</p>
i want it to be:
<!doctype html>
<html><head><!-- with all things in the head to make it work stand alone HTML of Angular app --></head>
<body>
<p>{{value}}</p>
</body>
</html>
So that i will be able to work on the partial as a stand alone app
Yes, you can use the ng-view in your template HTML file, something like:
<html ng-app="myApp">
<head>
...
<head>
<body ng-view>
</body>
</html>
Then in your $routeProvider you can use templateURL:, like:
$routeProvider.when('/register', {templateUrl: 'partials/register.html', controller: 'RegisterCtrl'});
The file partials/register.html is a complete HTML file.
So far the only answer i did found for this, is to actually use Angular with require.js - then I can leverage the text plugin and have my partials real apps.
The way to do it is to configure your app to load all templates using the text plugin of require with the strip option, then your views can have html with head and body that are ignored - so you can provide the necessary require.js files (it can share the same require.js configuration as the normal app if it is located at the same level as the normal app - i decided to place them in adjacent folders. but they do need different require.js main - so the main needs to reference the configuration)
Setting this up takes some effort, but it helps me develop large views with a lot of logic in them separately, and then just link them into my app as a view (while maintain the ability to access them separately, mostly for debugging)
What issues might I experience in having two different versions of AngularJS loaded into one page?
Obviously this seems like a stupid thing to do, but my use case is a page that uses AngularJS incorporating a third-party component that drags in its preferred version of AngularJS.
Update:
Found some info:
https://groups.google.com/forum/#!msg/angular/G8xPyD1F8d0/u1QNDNvcwW4J
https://github.com/angular/angular.js/pull/1535
Angular is really not prepared to co-exist with other version. But it's feasible.
First of all load angular library and make sure that before loading window.angular is empty:
<script src="vendor/angular/1.2.0/angular.min.js"></script>
<script src="app/app2.js"></script>
<script>
var angular2 = angular;
window.angular = null; // here we're cleaning angular reference
</script>
<script src="vendor/angular/1.0.5/angular.js"></script>
<script src="app/app1.js"></script>
<script>
var angular1 = angular;
</script>
Note that each application (app1.js, app2.js) for each version of angular should be loaded immediately after loading angular library.
Each JavaScript file of the application shoud be wrapped in self executing function (function(angular) { ... })(angular). Look at the example of app2.js:
(function(angular) {
angular.module('myApp2', []).
controller('App2Ctrl', function($scope) {
$scope.$watchCollection('[a, b, c]', function() {
console.log(angular.version.full);
});
});
})(angular);
Note that here I'm using $watchCollection which is only available for angular 1.2.x. By providing scope of anonymous function for each file you are forcing application to reach angular property instead of window.angular property.
Finally you have to bootstrap the application using manuall method:
<body>
<div id="myApp1" ng-controller="App1Ctrl">
</div>
<div id="myApp2" ng-controller="App2Ctrl">
</div>
<script>
angular1.bootstrap(document.getElementById('myApp1'), ['myApp1']);
angular2.bootstrap(document.getElementById('myApp2'), ['myApp2']);
</script>
</body>
Working plunker here. After running please check console window to see logged versions of angular used.
Great question! Like you, we were unable to uncover much on this topic...we are in the process of deploying a version of Angular with our product which will be embedded within client websites that could also have Angular already loaded.
Here is what we have done:
Modify the Angular source - do not use "window.angular" or "angular" in your implementation, choose some other variable or object property to house it. If you do use "window.angular" and/or "angular", it could break both applications if the versions are different.
Rename all delivered objects (directives, etc); otherwise, the other version of angular could attempt to process your directives.
Rename all CSS classes used by Angular (ng-cloak, etc). This will allow you to style your version of Angular separately from the other version.
Manually bootstrap your application, as described by 'kseb' above.
If you are going to completely name space AngularJS as I have described here, take care to not do a global search and replace because angular does need a "window" reference for registering events, and a few other places.
I just finished doing this at work and I am in the process of testing. I will update this answer with my results.
Matt Burke describes a process to wrap the Angular JS libs in a function to create a closure. Downside is that you cannot load Angular via a public CDN as you have customized the download.
http://www.mattburkedev.com/multiple-angular-versions-on-the-same-page/
Angular 2 will provide a new router with similar features to UI router, but that will also allow to have some routes in Angular 1 and others in Angular 2.
This router is currently being backported to Angular 1, see here a presentation from the developer of the new router explaining how this will work.
The idea behind a common cross-version router with support for both version is to help users upgrade from Angular 1 to Angular 2.
I have been working on an angular.js app that is growing wit many controllers,
all of the files are included in the index.html file, even if the current view does not use one of them, this apply to providers and other modules too.
how do i call only the controller that is needed depending on the routes, in the index.html?
i have an index.html file with the many script tags:
<script src="controller1.js"></script>
<script src="controller2.js"></script>
<script src="controller3.js"></script>
Update:
A better explanation of the question + answer.
http://weblogs.asp.net/dwahlin/archive/2013/05/22/dynamically-loading-controllers-and-views-with-angularjs-and-requirejs.aspx
What you are looking for is asynchronous modules and a loader that can pull them from the server. RequireJS is the first one that springs to mind. A seed project with examples of how to marry RequireJS and AngularJS can be found here.
You should let angular handle it for you, based on the route or url. you best option is to look at the routeProvider, the documentation is here.
usage looks like this:
$routeProvider.when('/Book/:bookId/ch/:chapterId', {
templateUrl: 'chapter.html',
controller: ChapterCntl
});
Another option would be using Ui router, which is an extension of the routeprovider. here is the project page.