Вставка в массив не обновляет представление - PullRequest
0 голосов
/ 09 января 2019

Я создал этот фальшивый разговор, который загружает последние 20 сообщений и следующие 20 или оставшиеся сообщения при прокрутке вверх страницы. По некоторым причинам оставшиеся сообщения успешно добавляются в массив vm.messages (я вижу это в консоли), но не становятся видимыми на экране в любое время после вызова loadMoreMessages позже.

Я абсолютно не знаю, почему это происходит ... Я подумал, что это может быть из-за того, что представление не обновляется правильно, однако, когда я создал функцию vm.reply, у него не возникает проблем с добавлением еще одного сообщения динамически.

Мне удалось загрузить сообщения от 30 до 10, как и ожидалось, но первые 10 не отображаются на экране после прокрутки вверх.

angular.module('app',['ui.bootstrap'])

.controller('mainCtrl', function($location, $anchorScroll, $document, $window) {
  var vm = this;
  vm.messagesInPart = 20; //number of messages in one part
  vm.messagesLoaded = 0;
  vm.conversation = [];
  vm.messages = [];
  
  $document.on('scroll', function() {
    if($window.scrollY === 0) {
       console.log('top of the page');
       loadMoreMessages();
    }
  });
  
  //fake conversation
  function getConversation() {
    for(var i = 1; i < 30; i++) {
      vm.conversation.push({
        side: 'left',
        badgeClass: 'info',
        badgeIconClass: 'glyphicon-comment',
        content: "My own message " + i,
        userName: ''
      });
    }
    
    scrollToTheReply();
  }
  
  getConversation();
  
  function loadMoreMessages() {
     vm.messagesLeftToLoad = vm.conversation.length - vm.messagesLoaded;

     if(vm.messagesLeftToLoad > 0) {
        var iterationsUpTo = vm.messagesLeftToLoad >= vm.messagesInPart ? vm.messagesLeftToLoad - vm.messagesInPart : 0;
       
        console.log('iterationsUpTo = ', iterationsUpTo);

        for(var i = vm.messagesLeftToLoad - 1; i >= iterationsUpTo; i--) {
          vm.messages.unshift({
             side: vm.conversation[i].side,
             badgeClass: vm.conversation[i].badgeClass,
             badgeIconClass: vm.conversation[i].badgeIconClass,
             userName: vm.conversation[i].userName,
             content: vm.conversation[i].content
          });

          vm.messagesLoaded++;
       }
       
       console.log('vm.messages = ', vm.messages);
     }
  }
  
  loadMoreMessages();
  
  function scrollToTheReply() {
	$location.hash('reply');
	$anchorScroll();
  }

  vm.reply = function() {
     vm.messages.push({
       side: 'left',
       badgeClass: 'info',
       badgeIconClass: 'glyphicon-comment',
       userName: '',
       content: 'Reply msg'
     });
  }
})
<html ng-app="app">
 <head>
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/rpocklin/angular-timeline/dist/angular-timeline-bootstrap.css"/>
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/rpocklin/angular-timeline/dist/angular-timeline.css"/>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.5/angular.min.js"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap.min.js"></script>
    <script src="https://cdn.jsdelivr.net/gh/rpocklin/angular-timeline/dist/angular-timeline.js"></script>
 </head>
 <body>
    <div ng-controller="mainCtrl as vm">
       <div style="float: left;">
          <timeline>
             <timeline-event ng-repeat="message in vm.messages" side="{{message.side}}">
                <timeline-badge class="{{message.badgeClass}}">
                   <i class="glyphicon {{message.badgeIconClass}}"></i>
                </timeline-badge>
                <timeline-panel class="{{message.badgeClass}}">
                   <timeline-heading>
                      <h4>{{message.userName}}</h4>
                   </timeline-heading>
                   <p>{{message.content}}</p>
                </timeline-panel>
              </timeline-event>
            </timeline>
         </div>
      <div style="margin-top:20px;">
        <button type="button" id="reply" ng-click="vm.reply()">Reply</button>
      </div>
    </div>
  </body>
 </html>

1 Ответ

0 голосов
/ 09 января 2019

Вы не в цикле дайджеста.

Запустите его с помощью функций $scope.$apply();, $scope.digest(); или $timeout(); при вызове функции loadMoreMessages();.

Пример:

$document.on('scroll', function() {
  if($window.scrollY === 0) {
     $timeout(function() {
      loadMoreMessages();
     });
  }
});

И не забудьте ввести $timeout в свой контроллер, если вы собираетесь его использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...