我希望能够同步2个md-virtual-repeat列表,以便它们的滚动位置相同。
我尝试使用md-top-index,这让我很接近,但滚动时它们仍然排在一起。 http://codepen.io/anon/pen/NxKvmy
HTML
<div ng-app="virtualRepeatScrollToDemo" ng-controller="AppCtrl as ctrl" class="scroll-demo">
<md-content class="md-padding">
<div class="wrapper">
<md-virtual-repeat-container id="vertical-container" md-top-index="ctrl.topIndex">
<div md-virtual-repeat="item in ctrl.items"
class="repeated-item" ng-class="{header: item.header}" flex>
{{item.text}}
</div>
</md-virtual-repeat-container>
</div>
<div class="wrapper">
<md-virtual-repeat-container id="vertical-container" md-top-index="ctrl.topIndex">
<div md-virtual-repeat="item in ctrl.items"
class="repeated-item" ng-class="{header: item.header}" flex>
{{item.text}}
</div>
</md-virtual-repeat-container>
</div>
</md-content>
</div>
JS
(function () {
'use strict';
angular
.module('virtualRepeatScrollToDemo', ['ngMaterial'])
.controller('AppCtrl', function($scope) {
this.years = [];
this.items = [];
var currentYear = new Date().getFullYear();
var monthNames = ['January', 'February', 'March', 'April', 'May', 'June','July', 'August', 'September', 'October', 'November', 'December'];
for (var y = currentYear; y >= (currentYear-20); y--) {
this.years.push(y);
this.items.push({year: y, text: y, header: true});
for (var m = 11; m >= 0; m--) {
this.items.push({year: y, month: m, text: monthNames[m]});
}
}
});
})();
CSS
.wrapper {
width: 400px;
float:left;
margin-left:20px;
}
#vertical-container {
height: 292px;
width: 400px;
}
#vertical-container .repeated-item {
border-bottom: 1px solid #ddd;
box-sizing: border-box;
height: 40px;
padding-top: 10px;
}
#vertical-container .repeated-item.header {
background-color: #3F51B5;
color: white;
text-align: center;
font-weight: bold;
}
#vertical-container md-content {
margin: 16px;
}
md-virtual-repeat-container {
border: solid 1px grey;
}
.md-virtual-repeat-container .md-virtual-repeat-offsetter {
padding-left: 16px;
}
我已经找到了一种看待滚动/转换位置的hackish方式,但我无法找到一种方法来做到这一点。有没有人知道这样做的方法?
感谢。
答案 0 :(得分:1)
以下是同步虚拟重复的指令。你这样使用它:
<md-virtual-repeat-container md-orient-horizontal
vr-scrollsync="scroll">
<div md-virtual-repeat="...">
...
</div>
</md-virtual-repeat-container>
在您的范围内,您必须将scroll属性初始化为空对象:
$scope.scroll = {};
(或者至少我不太了解Angular知道如何在不执行此操作的情况下在指令实例之间共享值 - 请帮助欢迎该主题)
我用水平重复进行测试,但它也适用于垂直重复。
angular.module("vrScrollsync", []).directive("vrScrollsync", ["$timeout", function($timeout) {
return {
scope: {
scroll: "=vrScrollsync"
},
link: function(scope, element, attrs) {
/**
* These flags avoid infinite recursion between Javascript
* event firing and Angular value changes.
*/
var skipWatch = false;
var skipEvent = false;
/**
* The scroller child of the virtual repeat container.
* It is not there yet at link time, so we set up a timer to obtain it.
*/
var scroller = null;
$timeout(function() {
scroller = element.find(".md-virtual-repeat-scroller");
scroller.bind("scroll", function() {
if (skipEvent) {
skipEvent = false;
return;
}
update(true);
});
});
function update(skipWatchIfChanged) {
var oldval = scope.scroll;
var newval = {
top: scroller[0].scrollTop,
left: scroller[0].scrollLeft
};
scope.scroll = newval;
var changed = oldval && (oldval.top != newval.top || oldval.left != newval.left)
if (skipWatchIfChanged && changed) skipWatch = true;
scope.$apply();
}
scope.$watch("scroll", function(v, old) {
if (skipWatch) {
skipWatch = false;
return;
}
if (scroller) {
skipEvent = true;
scroller[0].scrollTop = v.top;
scroller[0].scrollLeft = v.left;
}
});
}
};
}]);