aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Cross2013-07-24 10:17:24 -0700
committerJeff Cross2013-08-09 13:14:12 -0700
commit3ee744cc63a24b127d6a5f632934bb6ed2de275a (patch)
treed66bab80608d1ef959fd7fd871e9493dad24d928
parent94ec84e7b9c89358dc00e4039009af9e287bbd05 (diff)
downloadangular.js-3ee744cc63a24b127d6a5f632934bb6ed2de275a.tar.bz2
fix(re-bootstrap): Throw an error when bootstrapping a bootstrapped element.
Nothing would prevent a user from accidentally calling angular.bootstrap on an element that had already been bootstrapped. If this was done, odd behavior could manifest in an application, causing different scopes to update the same DOM, and causing debugger confusion. This fix adds a check inside of angular.bootstrap to check if the passed-in element already has an injector, and if so, will throw an error.
-rw-r--r--docs/content/error/ng/btstrpd.ngdoc29
-rw-r--r--src/Angular.js6
-rw-r--r--test/AngularSpec.js26
3 files changed, 61 insertions, 0 deletions
diff --git a/docs/content/error/ng/btstrpd.ngdoc b/docs/content/error/ng/btstrpd.ngdoc
new file mode 100644
index 00000000..401e2767
--- /dev/null
+++ b/docs/content/error/ng/btstrpd.ngdoc
@@ -0,0 +1,29 @@
+@ngdoc error
+@name ng:btstrpd
+@fullName App Already Bootstrapped with this Element
+@description
+
+Occurs when calling angular.bootstrap on an element that has already been bootstrapped.
+
+This usually happens when you accidentally use both `ng-app` and `angular.bootstrap` to bootstrap an application.
+
+```
+<html>
+...
+ <body ng-app="myApp">
+ <script>
+ angular.bootstrap(document.body, ['myApp']);
+ </script>
+ </body>
+</html>
+```
+
+Note that for bootrapping purposes, the `<html>` element is the same as `document`, so the following will also throw an error.
+```
+<html>
+...
+<script>
+ angular.bootstrap(document, ['myApp']);
+</script>
+</html>
+```
diff --git a/src/Angular.js b/src/Angular.js
index 1a90f8bc..90c7234a 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -1049,6 +1049,12 @@ function angularInit(element, bootstrap) {
function bootstrap(element, modules) {
var doBootstrap = function() {
element = jqLite(element);
+
+ if (element.injector()) {
+ var tag = (element[0] === document) ? 'document' : startingTag(element);
+ throw ngMinErr('btstrpd', "App Already Bootstrapped with this Element '{0}'", tag);
+ }
+
modules = modules || [];
modules.unshift(['$provide', function($provide) {
$provide.value('$rootElement', element);
diff --git a/test/AngularSpec.js b/test/AngularSpec.js
index 56fc985c..f049c2fd 100644
--- a/test/AngularSpec.js
+++ b/test/AngularSpec.js
@@ -656,6 +656,32 @@ describe('angular', function() {
/\[\$injector:modulerr] Failed to instantiate module doesntexist due to:\n.*\[\$injector:nomod] Module 'doesntexist' is not available! You either misspelled the module name or forgot to load it\./
);
});
+
+
+ it('should complain if an element has already been bootstrapped', function () {
+ var element = jqLite('<div>bootstrap me!</div>');
+ angular.bootstrap(element);
+
+ expect(function () {
+ angular.bootstrap(element);
+ }).toThrowMatching(
+ /\[ng:btstrpd\] App Already Bootstrapped with this Element '<div class="?ng\-scope"?( ng\-[0-9]+="?[0-9]+"?)?>'/i
+ );
+
+ dealoc(element);
+ });
+
+
+ it('should complain if manually bootstrapping a document whose <html> element has already been bootstrapped', function () {
+ angular.bootstrap(document.getElementsByTagName('html')[0]);
+ expect(function () {
+ angular.bootstrap(document);
+ }).toThrowMatching(
+ /\[ng:btstrpd\] App Already Bootstrapped with this Element 'document'/i
+ );
+
+ dealoc(document);
+ })
});