#angularjs
#angularjs
Вопрос:
У меня есть список элементов, восстановленных асинхронным вызовом, и этот список отображается с помощью ng-repeat
. Поскольку контейнер div этого списка имеет фиксированную высоту (400 пикселей) Я хочу, чтобы полоса прокрутки была внизу. И для этого мне нужно scrollHeight
. Но scrollHeight
in postLink
— это не конечная высота, а начальная высота.
Пример
ppChat.tpl.html
<!-- Height of "chatroom" is "400px" -->
<div class="chatroom">
<!-- Height of "messages" after all messages have been loaded is "4468px" -->
<div class="messages" ng-repeat="message in chat.messages">
<chat-message data="message"></chat-message>
</div>
</div>
ppChat.js
// [...]
compile: function(element) {
element.addClass('pp-chat');
return function(scope, element, attrs, PpChatController) {
var messagesDiv;
// My idea was to wait until the messages have been loaded...
PpChatController.messages.$loaded(function() {
// ...and then recompile the messages div container
messagesDiv = $compile(element.children()[0])(scope);
// Unfortunately this doesn't work. "messagesDiv[0].scrollHeight" still has its initial height of "400px"
});
}
}
Может кто-нибудь объяснить, что я здесь пропустил?
По мере необходимости вот его часть
Комментарии:
1. пожалуйста, создайте plunkr, чтобы другие могли редактировать / улучшать ваш код.
2. откуда у вас высота прокрутки 2000 пикселей?
Ответ №1:
Вы можете получить scrollHeight
из div после обновления DOM, выполнив это следующим образом.
Приведенная ниже директива устанавливает наблюдение за массивом, то есть коллекцией, и использует службу $timeout для ожидания обновления DOM, а затем прокручивается до нижней части div.
chatDirective.$inject = ['$timeout'];
function chatDirective($timeout) {
return {
require: 'chat',
scope: {
messages: '='
},
templateUrl: 'partials/chat.tpl.html',
bindToController: true,
controllerAs: 'chat',
controller: ChatController,
link: function(scope, element, attrs, ChatController) {
scope.$watchCollection(function () {
return scope.chat.messages;
}, function (newValue, oldValue) {
if (newValue.length) {
$timeout(function () {
var chatBox = document.getElementsByClassName('chat')[0];
console.log(element.children(), chatBox.scrollHeight);
chatBox.scrollTop = chatBox.scrollHeight;
});
}
});
}
};
}
Обновленный плунжер находится здесь.
Также в вашем контроллере вы написали как,
var Controller = this;
this.messages = [];
Лучше писать так, здесь vm означает ViewModel
AppController.$inject = ['$timeout'];
function AppController($timeout) {
var vm = this;
vm.messages = [];
$timeout(
function() {
for (var i = 0; i < 100; i ) {
vm.messages.push({
message: getRandomString(),
created: new Date()
});
}
},
3000
);
}