Open ornic opened 4 years ago
@ornic If you are going to augment Viewport module, an easier approach might be as follows.
Template:
<ul class="list-group" ui-scroll-viewport="$ctrl.checkRestrictHeight()">
Directive:
.directive('uiScrollViewport', function () {
return {
restrict: 'A',
scope: { window: '=uiScrollViewport' }, // new line, assign directive attr value to scope.window
controller: [
// ...
Viewport:
const ctrl = viewportController;
const isViewport = ctrl && ctrl.scope && ctrl.scope.window !== false;
const scope = isViewport ? ctrl.scope : $rootScope;
const viewport = isViewport && ctrl.viewport ? ctrl.viewport : angular.element(window);
const container = isViewport && ctrl.container ? ctrl.container : undefined;
Note, the explicit check is used: !== false
-- it is necessary for the case when a user doesn't pass any value to the "ui-scroll-viewport" attribute but expects the Viewport to be present.
This way code looks more readable than in my crude variant. But I found that after defining scope in .directive
it is unable to make an adaptor in viewportController.scope
, but constantly setting viewport.scope to $rootScope fixed the problem (for me, with using ui-scroll via component). But I assume that in future (more usecases inside one app) this approach may backfire.
UPD: I looked further and it seems that this approach should be Ok, since the only result AFAIK is always using scope of uiScroll
directive.
I didn't meet any issues with the Adapter when using the suggested approach.
I also found the very handy method of using full-window scroll: with some block of text before the list. But there is a problem on the way.
This is the easy correction of your example. This div goes before the list
<div style="
height: 300px;
text-align: center;
border: 1px solid lightgreen;
vertical-align: middle;
padding: 100px;
">Hello! I'm 300px of height.</div>
and we limit the list with index -100.
And then we lose ability to correctly identify first and last element:
I'm trying to find the way to overcome this. :)
....
That was... interesting :))) As a result I adjusted *Pos
functions with an idea to use container top offset and scrollHeight to compensate:
bottomDataPos: function bottomDataPos() {
var scrollHeight = viewport[0].scrollHeight;
scrollHeight = scrollHeight != null ? scrollHeight : viewport[0].document.documentElement.scrollHeight;
let btmPadding = bottomPadding.height();
if (container && container[0] != viewport[0]) { // the only possible case: viewport = window && container != window
if (btmPadding > 0) { // consider space under the container
return container[0].scrollHeight - btmPadding;
}
scrollHeight -= container.offset().top;
}
return scrollHeight - btmPadding;
},
topDataPos: function topDataPos() {
let topDataPos = topPadding.height();
return topDataPos;
},
bottomVisiblePos: function bottomVisiblePos() {
let viewPortHeight = viewport.outerHeight();
if (container && container[0] != viewport[0]) {
let offset = container.offset().top - viewport.scrollTop();
if (offset > 0) viewPortHeight -= offset;
}
return viewport.topVisiblePos() + viewPortHeight;
},
topVisiblePos: function topVisiblePos() {
let topVisiblePos = viewport.scrollTop();
if (container && container[0] != viewport[0]) {
topVisiblePos -= container.offset().top;
if (topVisiblePos < 0) topVisiblePos = 0; // no negative positions :)
}
return topVisiblePos;
}
I am trying to use great ui-scroll module inside one of the components. This is a (surprise!) list, but i need to show it both inside window (no viewport) or inside popup (with viewport).
The only way I know to tell ui-scroll about viewport is
ui-scroll-viewport
attribute. And the only way I can tell Angular about optional attribute isng-attr-
prefix. I want it to be optional attribute, since I hate to copy-paste the same code in ng-switches.And this is a place when things get interesting. According to https://github.com/angular/angular.js/issues/16441 ui-scroll gets information about
ui-scroll-viewport
attribute before evaluation ofng-attr-ui-scroll-viewport
value.May be someone will point me to more "right" solution. But for now I had to patch ui-scroll.js file.
1) I send the
max-height
style inside some param to the component2) I check the result of $eval for
ng-attr-ui-scroll-viewport
value