Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 6c5a05a

Browse files
committed
feat(jqLite): add .controller() method
extend JQuery with .controller() method which retrieves the closest controller for a given element
1 parent 192ff61 commit 6c5a05a

File tree

3 files changed

+49
-15
lines changed

3 files changed

+49
-15
lines changed

src/Angular.js

+1
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,7 @@ function bindJQuery() {
928928
jqLite = jQuery;
929929
extend(jQuery.fn, {
930930
scope: JQLitePrototype.scope,
931+
controller: JQLitePrototype.controller,
931932
injector: JQLitePrototype.injector,
932933
inheritedData: JQLitePrototype.inheritedData
933934
});

src/jqLite.js

+25-13
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,13 @@
6060
*
6161
* ## In addtion to the above, Angular privides an additional method to both jQuery and jQuery lite:
6262
*
63-
* - `scope()` - retrieves the current Angular scope of the element.
64-
* - `injector()` - retrieves the Angular injector associated with application that the element is
65-
* part of.
63+
* - `controller(name)` - retrieves the controller of the current element or its parent. By default
64+
* retrieves controller associated with the `ng-controller` directive. If `name` is provided as
65+
* camelCase directive name, then the controller for this directive will be retrieved (e.g.
66+
* `'ngModel'`).
67+
* - `injector()` - retrieves the injector of the current element or its parent.
68+
* - `scope()` - retrieves the {@link api/angular.module.ng.$rootScope.Scope scope} of the current
69+
* element or its parent.
6670
* - `inheritedData()` - same as `data()`, but walks up the DOM until a value is found or the top
6771
* parent element is reached.
6872
*
@@ -268,6 +272,18 @@ function JQLiteAddNodes(root, elements) {
268272
}
269273
}
270274

275+
function JQLiteController(element, name) {
276+
return JQLiteInheritedData(element, '$' + (name || 'ngController' ) + 'Controller');
277+
}
278+
279+
function JQLiteInheritedData(element, name, value) {
280+
element = jqLite(element);
281+
while (element.length) {
282+
if (value = element.data(name)) return value;
283+
element = element.parent();
284+
}
285+
}
286+
271287
//////////////////////////////////////////
272288
// Functions which are declared directly.
273289
//////////////////////////////////////////
@@ -321,20 +337,16 @@ function isBooleanAttr(element, name) {
321337

322338
forEach({
323339
data: JQLiteData,
324-
inheritedData: function(element, name, value) {
325-
element = jqLite(element);
326-
while (element.length) {
327-
if (value = element.data(name)) return value;
328-
element = element.parent();
329-
}
330-
},
340+
inheritedData: JQLiteInheritedData,
331341

332342
scope: function(element) {
333-
return jqLite(element).inheritedData('$scope');
343+
return JQLiteInheritedData(element, '$scope');
334344
},
335345

346+
controller: JQLiteController ,
347+
336348
injector: function(element) {
337-
return jqLite(element).inheritedData('$injector');
349+
return JQLiteInheritedData(element, '$injector');
338350
},
339351

340352
removeAttr: function(element,name) {
@@ -449,7 +461,7 @@ forEach({
449461

450462
// JQLiteHasClass has only two arguments, but is a getter-only fn, so we need to special-case it
451463
// in a way that survives minification.
452-
if (((fn.length == 2 && fn !== JQLiteHasClass) ? arg1 : arg2) === undefined) {
464+
if (((fn.length == 2 && (fn !== JQLiteHasClass && fn !== JQLiteController)) ? arg1 : arg2) === undefined) {
453465
if (isObject(arg1)) {
454466
// we are a write, but the object properties are the key/values
455467
for(i=0; i < this.length; i++) {

test/jqLiteSpec.js

+23-2
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,8 @@ describe('jqLite', function() {
140140
describe('injector', function() {
141141
it('should retrieve injector attached to the current element or its parent', function() {
142142
var template = jqLite('<div><span></span></div>'),
143-
span = template.children().eq(0),
144-
injector = angular.bootstrap(template);
143+
span = template.children().eq(0),
144+
injector = angular.bootstrap(template);
145145

146146

147147
expect(span.injector()).toBe(injector);
@@ -150,6 +150,27 @@ describe('jqLite', function() {
150150
});
151151

152152

153+
describe('controller', function() {
154+
it('should retrieve controller attached to the current element or its parent', function() {
155+
var div = jqLite('<div><span></span></div>'),
156+
span = div.find('span');
157+
158+
div.data('$ngControllerController', 'ngController');
159+
span.data('$otherController', 'other');
160+
161+
expect(span.controller()).toBe('ngController');
162+
expect(span.controller('ngController')).toBe('ngController');
163+
expect(span.controller('other')).toBe('other');
164+
165+
expect(div.controller()).toBe('ngController');
166+
expect(div.controller('ngController')).toBe('ngController');
167+
expect(div.controller('other')).toBe(undefined);
168+
169+
dealoc(div);
170+
});
171+
});
172+
173+
153174
describe('data', function() {
154175
it('should set and get and remove data', function() {
155176
var selected = jqLite([a, b, c]);

0 commit comments

Comments
 (0)