Skip to content

Commit a6a32e9

Browse files
committed
Custom directive "Controller As" assignment
1 parent 46ef8e8 commit a6a32e9

File tree

2 files changed

+69
-7
lines changed

2 files changed

+69
-7
lines changed

src/ui-scroll.js

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ angular.module('ui.scroll', [])
417417
}
418418

419419
function Adapter($attr, viewport, buffer, adjustBuffer, element) {
420+
const hasViewport = !!viewport.scope();
420421
const viewportScope = viewport.scope() || $rootScope;
421422
let disabled = false;
422423
let self = this;
@@ -514,31 +515,48 @@ angular.module('ui.scroll', [])
514515
let target = match[1];
515516
let onControllerName = match[2];
516517

517-
let parseControllers = (controllerName, as = false) => {
518+
// ng-controller attr based DOM parsing
519+
let parseNgCtrlAttrs = (controllerName, as = false) => {
518520
let candidate = element;
519521
while (candidate.length) {
522+
let candidateScope = candidate.scope();
520523
let candidateName = (candidate.attr('ng-controller') || '').match(/(\w(?:\w|\d)*)(?:\s+as\s+(\w(?:\w|\d)*))?/);
521524
if (candidateName && candidateName[as ? 2 : 1] === controllerName) {
522-
scope = candidate.scope();
523-
break;
525+
scope = candidateScope;
526+
return true;
524527
}
525528
candidate = candidate.parent();
526529
}
527530
};
528531

529-
if (onControllerName) { // 'on' syntax parsing
532+
// scope based DOM pasrsing
533+
let parseScopes = (controllerName) => {
534+
let candidate = element;
535+
while (candidate.length) {
536+
let candidateScope = candidate.scope();
537+
if (candidateScope && candidateScope.hasOwnProperty(controllerName) && candidateScope[controllerName].constructor.name === 'controller') {
538+
scope = candidateScope;
539+
return true;
540+
}
541+
candidate = candidate.parent();
542+
}
543+
};
544+
545+
if (onControllerName) { // 'on' syntax DOM parsing (adapter="adapter on ctrl")
530546
scope = null;
531-
parseControllers(onControllerName);
547+
parseNgCtrlAttrs(onControllerName);
532548
if (!scope) {
533549
throw new Error('Failed to locate target controller \'' + onControllerName + '\' to inject \'' + target + '\'');
534550
}
535551
}
536-
else { // try to parse with 'Controller As' syntax
552+
else { // try to parse DOM with 'Controller As' syntax (adapter="ctrl.adapter")
537553
let controllerAsName;
538554
let dotIndex = target.indexOf('.');
539555
if(dotIndex > 0) {
540556
controllerAsName = target.substr(0, dotIndex);
541-
parseControllers(controllerAsName, true);
557+
if(!parseNgCtrlAttrs(controllerAsName, true) && !hasViewport) {
558+
parseScopes(controllerAsName); // the case of custom Directive/Component
559+
}
542560
}
543561
}
544562

test/AssigningSpec.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,24 @@ describe('uiScroll', function () {
1515
myApp.controller('MyBottomController', function($scope) {
1616
$scope.name = 'MyBottomController';
1717
});
18+
var customDirTemplate;
19+
myApp.directive('myDir', function() {
20+
return {
21+
restrict: 'E',
22+
controllerAs: 'ctrl',
23+
controller: function () { this.show = true; },
24+
template: customDirTemplate
25+
};
26+
});
27+
28+
var setDir = function(viewport) {
29+
customDirTemplate =
30+
'<div ' + (viewport ? 'ui-scroll-viewport' : '') +' style="height:200px" ng-if="ctrl.show">' +
31+
'<div ui-scroll="item in myMultipageDatasource" adapter="ctrl.adapter">' +
32+
'{{$index}}: {{item}}' +
33+
'</div>' +
34+
'</div>';
35+
};
1836

1937
beforeEach(module('myApp'));
2038

@@ -172,6 +190,32 @@ describe('uiScroll', function () {
172190
'</div>';
173191
executeTest(template, 'MyInnerController as ctrl', 'ctrl');
174192
});
193+
194+
it('should work for custom directive with "Controller As" syntax (viewport)', function () {
195+
setDir(true);
196+
var template =
197+
'<div ng-controller="MyTopController">' +
198+
'<div ng-controller="MyInnerController" ng-if="name">' +
199+
'<div ng-controller="MyBottomController" ng-if="name">' +
200+
'<my-dir></my-dir>' +
201+
'</div>' +
202+
'</div>' +
203+
'</div>';
204+
executeTest(template, 'MyBottomController', 'ctrl');
205+
});
206+
207+
it('should work for custom directive with "Controller As" syntax (no viewport)', function () {
208+
setDir(false);
209+
var template =
210+
'<div ng-controller="MyTopController">' +
211+
'<div ng-controller="MyInnerController" ng-if="name">' +
212+
'<div ng-controller="MyBottomController" ng-if="name">' +
213+
'<my-dir></my-dir>' +
214+
'</div>' +
215+
'</div>' +
216+
'</div>';
217+
executeTest(template, 'MyBottomController', 'ctrl');
218+
});
175219
});
176220

177221
});

0 commit comments

Comments
 (0)