aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMisko Hevery2011-02-07 13:28:42 -0800
committerMisko Hevery2011-02-16 00:48:22 -0500
commit0a5c00abf8664fdbdc5d16b13adb1989b4531cdf (patch)
tree42d9426de8aa7917ba2dc127ee35dbc5890d7877
parenta004d487c4bb48b2bec19b60bc5ddc5244029be5 (diff)
downloadangular.js-0a5c00abf8664fdbdc5d16b13adb1989b4531cdf.tar.bz2
Add public API to retrieve scope from element.
-rw-r--r--CHANGELOG.md3
-rw-r--r--docs/angular.element.ngdoc13
-rw-r--r--src/Angular.js9
-rw-r--r--src/Compiler.js12
-rw-r--r--src/jqLite.js9
-rw-r--r--src/widgets.js2
-rw-r--r--test/CompilerSpec.js20
-rw-r--r--test/jqLiteSpec.js31
8 files changed, 61 insertions, 38 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 46323915..de7b3f4f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,9 @@
- setting the parent scope for scopes created by the service via `#parent()`
- reloading the current route via `#reload()`
+### API
+- added `angular.element(...).scope()` method to retrieve scope for a given element.
+
### Bug Fixes
- <option> value attribute gets clobbered when the element contains new line character(s).
- <ng:view> widget now works when nested inside an <ng:include> widget
diff --git a/docs/angular.element.ngdoc b/docs/angular.element.ngdoc
index a636cc25..90025799 100644
--- a/docs/angular.element.ngdoc
+++ b/docs/angular.element.ngdoc
@@ -9,16 +9,17 @@ Wraps a raw DOM element or HTML string as [jQuery](http://jquery.com) element.
jQuery is loaded or a function that wraps the element or string in angular's jQuery lite
implementation.
-Real jQuery always takes precedence if it was loaded before angular.
+Real jQuery always takes precedence (as long as it was loaded before `DOMContentEvent`)
Angular's jQuery lite implementation is a tiny API-compatible subset of jQuery which allows
-angular to manipulate DOM. The functions implemented are usually just the basic versions of
-them and might not support arguments and invocation styles.
+angular to manipulate DOM. The jQuery lite implements only a subset of jQuery api, with the
+focus on the most commonly needed functionality and minimal footprint. For this reason only a
+limited number of jQuery methods, arguments and invocation styles are supported.
NOTE: All element references in angular are always wrapped with jQuery (lite) and are never
raw DOM references.
-Angular's jQuery lite implements these functions:
+## Angular's jQuery lite implements these functions:
- [addClass()](http://api.jquery.com/addClass/)
- [after()](http://api.jquery.com/after/)
@@ -39,5 +40,9 @@ Angular's jQuery lite implements these functions:
- [text()](http://api.jquery.com/text/)
- [trigger()](http://api.jquery.com/trigger/)
+## Additionally these methods are available in both jQuery and jQuery lite version.
+
+- `scope()` - retrieves the current angular scope of the element.
+
@param {string|DOMElement} element HTML string or DOMElement to be wrapped into jQuery.
@returns {Object} jQuery object.
diff --git a/src/Angular.js b/src/Angular.js
index b856aa24..9a1ab4a2 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -1032,5 +1032,12 @@ function angularJsConfig(document, config) {
function bindJQuery(){
// bind to jQuery if present;
jQuery = window.jQuery;
- angular.element = jqLite = jQuery || jqLiteWrap;
+ // reset to jQuery or default to us.
+ if (window.jQuery) {
+ jqLite = window.jQuery;
+ jqLite.fn.scope = JQLite.prototype.scope;
+ } else {
+ jqLite = jqLiteWrap;
+ }
+ angular.element = jqLite;
}
diff --git a/src/Compiler.js b/src/Compiler.js
index 472ec625..d1505404 100644
--- a/src/Compiler.js
+++ b/src/Compiler.js
@@ -69,18 +69,6 @@ Template.prototype = {
}
};
-/*
- * Function walks up the element chain looking for the scope associated with the give element.
- */
-function retrieveScope(element) {
- var scope;
- element = jqLite(element);
- while (element && element.length && !(scope = element.data($$scope))) {
- element = element.parent();
- }
- return scope;
-}
-
///////////////////////////////////
//Compiler
//////////////////////////////////
diff --git a/src/jqLite.js b/src/jqLite.js
index ad7734c9..206c1d70 100644
--- a/src/jqLite.js
+++ b/src/jqLite.js
@@ -87,6 +87,15 @@ JQLite.prototype = {
})(this[0]);
},
+ scope: function() {
+ var scope, element = this;
+ while (element && element.length && !(scope = element.data($$scope))) {
+ element = element.parent();
+ }
+ return scope;
+ },
+
+
ready: function(fn) {
var fired = false;
diff --git a/src/widgets.js b/src/widgets.js
index 461684ac..f8efae60 100644
--- a/src/widgets.js
+++ b/src/widgets.js
@@ -561,7 +561,7 @@ angularWidget('option', function(){
return function(option) {
var select = option.parent();
var isMultiple = select[0].type == 'select-multiple';
- var scope = retrieveScope(select);
+ var scope = select.scope();
var model = modelAccessor(scope, select);
//if parent select doesn't have a name, don't bother doing anything any more
diff --git a/test/CompilerSpec.js b/test/CompilerSpec.js
index 498ee060..291a5011 100644
--- a/test/CompilerSpec.js
+++ b/test/CompilerSpec.js
@@ -166,24 +166,4 @@ describe('compiler', function(){
scope = compile('A---B---C===D');
expect(sortedHtml(scope.$element)).toEqual('<div>A<hr></hr>B<hr></hr>C<p></p>D</div>');
});
-
-
- describe('retrieveScope', function() {
- it('should retrieve scope attached to the current element', function() {
- scope = compile('<i>foo</i>');
- expect(retrieveScope(scope.$element)).toBe(scope);
- });
-
- it('should walk up the dom to find scope', function() {
- scope = compile('<ul><li><p><b>deep deep</b><p></li></ul>');
- var deepChild = scope.$element[0].getElementsByTagName('b')[0];
- expect(retrieveScope(deepChild)).toBe(scope);
- });
-
- it('should return undefined when no scope was found', function() {
- var html = jqLite('<ul><li><p><b>deep deep</b><p></li></ul>'),
- deepChild = html[0].getElementsByTagName('b')[0];
- expect(retrieveScope(deepChild)).toBeNull();
- });
- });
});
diff --git a/test/jqLiteSpec.js b/test/jqLiteSpec.js
new file mode 100644
index 00000000..da8ab206
--- /dev/null
+++ b/test/jqLiteSpec.js
@@ -0,0 +1,31 @@
+describe('jqLite', function(){
+ var scope;
+
+ beforeEach(function(){
+ scope = angular.scope();
+ });
+
+ describe('scope', function() {
+ it('should retrieve scope attached to the current element', function() {
+ var element = jqLite('<i>foo</i>');
+ element.data('$scope', scope);
+ expect(element.scope()).toBe(scope);
+ dealoc(element);
+ });
+
+ it('should walk up the dom to find scope', function() {
+ var element = jqLite('<ul><li><p><b>deep deep</b><p></li></ul>');
+ var deepChild = jqLite(element[0].getElementsByTagName('b')[0]);
+ element.data('$scope', scope);
+ expect(deepChild.scope()).toBe(scope);
+ dealoc(element);
+ });
+
+ it('should return undefined when no scope was found', function() {
+ var element = jqLite('<ul><li><p><b>deep deep</b><p></li></ul>');
+ var deepChild = jqLite(element[0].getElementsByTagName('b')[0]);
+ expect(deepChild.scope()).toBeNull();
+ dealoc(element);
+ });
+ });
+});