У меня есть отображение сообщений чата, в котором отображаются самые старые сообщения вверху и самые последние сообщения в нижней части. Я использую ng-repeat
в массиве $scope.messages
, и новые сообщения чата динамически добавляются в этот массив. У ng-repeat
есть компонент фильтра orderBy
, который помогает сортировать сообщения по дате создания.Как использовать ng-if правильно с обновленной областью ng-repeat, которая использует фильтр orderBy
Я пытаюсь использовать ng-if
, чтобы скрыть некоторые аспекты HTML (аватара пользователя, имя пользователя, msg-timestamp и т. Д.), Когда сообщение отправляется одним и тем же пользователем в тот же день. Однако моя логика прикручивается, когда добавляется новое сообщение в массив $scope.messages
.
укороченная версия HTML:
<div class="ListMessage" ng-repeat="message in messages | orderBy: 'created' track by message.xpid">
<div class="Avatar" ng-if="headerDisplay(message)">
</div>
<div class="TimeStamp" ng-if="headerDisplay(message)">
</div>
<div class="MessageContent">
</div>
</div>
И вот применимый контроллер чата:
$scope.messages = [];
// use an HTTP service to retrieve messages...
$scope.$on('messages_updated', function(event, data){
$scope.messages = data;
};
$scope.headerDisplay = function(message){
var idx = $scope.messages.indexOf(message);
var curMsg = $scope.messages[idx];
var nextMsg;
// if last msg in array (this is actually the 1st msg sent cuz of the orderBy) --> display avatar
if (idx === $scope.messages.length-1){
return true;
}
// if not the last msg in array (not the 1st sent)...
if (idx !== $scope.messages.length-1){
nextMsg = $scope.messages[idx+1];
var nextMsgDate = new Date(nextMsg.created);
var curMsgDate = new Date(curMsg.created);
// if msg is on a new day --> display avatar
if (curMsgDate.getDate() !== nextMsgDate.getDate()){
return true;
} else if (curMsg.fullProfile.displayName !== nextMsg.fullProfile.displayName){
// if msg is from diff user --> display avatar
return true;
} else {
return false;
}
}
};
Этот код работает на первый взгляд. Первоначально из-за фильтра orderBy
сообщение с последним индексом $scope.messages
фактически является первым сообщением, и сообщение в - это последнее добавленное сообщение.
Но всякий раз, когда добавляется новое сообщение, Угловое динамически обновляет объем, и на долю секунды до orderBy
фильтра применяется, что новое сообщение на последнем индексе $scope.messages
. Это отбрасывает логику моего метода ng-if
, так что каждое новое сообщение от того же пользователя появляется с элементами HTML, которые я хочу скрывать (т. Е. Возвращает true по методу ng-if
).
Согласно обширному console.logging
с моей стороны, во время компиляции HTML для ng-if
, сообщение на индекс остается второй до последнего отправленного сообщения (не самый последний), и новейший, последнее сообщение на самом деле является элементом в последнем индексе массива. Это приводит к тому, что первый оператор if
вступает в силу и отображаемые элементы HTML для каждого нового сообщения, отправленного одним и тем же пользователем в тот же день (если только я не обновляю страницу, в которой все отображается правильно).
Любые обходные пути, о которых каждый может подумать?
ли лучше, если вы используете значение «$ индекс» предоставленный нг-повтор объема, вместо того, чтобы пытаться для поиска индекса в массиве сообщений? –
Да, это так. Я не думаю, что это повлияло на этот вопрос. – Seeeyonnn
У меня нет времени на полный ответ, но в основном вам нужно назначить результат фильтра временному массиву. Посмотрите на 'ng-repeat as' –