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

Commit 6ddda90

Browse files
drpicoxNarretz
authored andcommitted
feat(ngRef): 3. bind to any expression
Closes #14080
1 parent 73e818d commit 6ddda90

File tree

3 files changed

+15
-80
lines changed

3 files changed

+15
-80
lines changed

docs/content/error/ngRef/badident.ngdoc

-37
This file was deleted.

src/ng/directive/ngRef.js

+9-16
Original file line numberDiff line numberDiff line change
@@ -177,40 +177,33 @@
177177
* </example>
178178
*
179179
*/
180-
var ngRefDirective = function() {
181-
var ngRefMinErr = minErr('ngRef');
182-
180+
var ngRefDirective = ['$parse',function($parse) {
183181
return {
184182
priority: -1,
185183
restrict: 'A',
186184
compile: function(tElement, tAttrs) {
187185
// gets the expected controller name, converts <data-some-thing> into "someThing"
188186
var controllerName = directiveNormalize(nodeName_(tElement));
189187

190-
// get the symbol name where to set the reference in the scope
191-
var symbolName = tAttrs.ngRef;
192-
193-
if (symbolName && (!/^[$a-zA-Z_][$a-zA-Z0-9_]*$/.test(symbolName) ||
194-
/^(null|undefined|this|\$parent|\$root|\$id)$/.test(symbolName))) {
195-
throw ngRefMinErr('badident', 'alias \'{0}\' is invalid --- must be a valid JS identifier which is not a reserved name.',
196-
symbolName);
197-
}
188+
// get the expression for value binding
189+
var getter = $parse(tAttrs.ngRef);
190+
var setter = getter.assign;
198191

199192
return function(scope, element) {
200193
// gets the controller of the current component or the current DOM element
201194
var controller = element.data('$' + controllerName + 'Controller');
202195
var value = controller || element[0];
203-
scope[symbolName] = value;
196+
setter(scope, value);
204197

205-
// when the element is removed, remove it from the scope assignment (nullify it)
198+
// when the element is removed, remove it (nullify it)
206199
element.on('$destroy', function() {
207200
// only remove it if value has not changed,
208201
// carefully because animations (and other procedures) may duplicate elements
209-
if (scope[symbolName] === value) {
210-
scope[symbolName] = null;
202+
if (getter(scope) === value) {
203+
setter(scope, null);
211204
}
212205
});
213206
};
214207
}
215208
};
216-
};
209+
}];

test/ng/directive/ngRefSpec.js

+6-27
Original file line numberDiff line numberDiff line change
@@ -107,33 +107,12 @@ describe('ngRef', function() {
107107
expect($rootScope.myComponent).toBe(enteringController);
108108
}));
109109

110-
it('should throw if alias identifier is not a simple identifier',
111-
inject(function($exceptionHandler) {
112-
forEach([
113-
'null',
114-
'this',
115-
'undefined',
116-
'$parent',
117-
'$root',
118-
'$id',
119-
'obj[key]',
120-
'obj["key"]',
121-
'obj[\'key\']',
122-
'obj.property',
123-
'foo=6'
124-
], function(identifier) {
125-
var escapedIdentifier = identifier.replace(/"/g, '&quot;');
126-
var template = '<my-component ng-ref="' + escapedIdentifier + '"></my-component>';
127-
var element = $compile(template)($rootScope);
128-
129-
expect($exceptionHandler.errors.length).toEqual(1, identifier);
130-
expect($exceptionHandler.errors.shift()[0]).toEqualMinErr('ngRef', 'badident',
131-
'alias \'' + identifier + '\' is invalid --- must be a valid JS identifier ' +
132-
'which is not a reserved name');
133-
134-
dealoc(element);
135-
});
136-
}));
110+
it('should allow bind to a parent controller', function() {
111+
$rootScope.$ctrl = {};
112+
113+
$compile('<my-component ng-ref="$ctrl.myComponent"></my-component>')($rootScope);
114+
expect($rootScope.$ctrl.myComponent).toBe(myComponentController);
115+
});
137116

138117
});
139118

0 commit comments

Comments
 (0)