我有一个聊天消息显示,顶部显示最旧的消息,底部显示最新的消息。我在数组ng-repeat
上使用一个$scope.messages
,新的聊天消息会动态添加到该数组中。有ng-repeat
一个orderBy
过滤器组件来帮助按创建日期对消息进行排序。
ng-if
当同一用户在同一天发送消息时,我试图用来隐藏 HTML 的某些方面(用户的头像、姓名、msg 时间戳等)。但是,当向数组添加新消息时,我的逻辑就搞砸了。$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
消息实际上是第一条消息,而位于0索引处的消息是最后添加的消息。
但是,每当添加新消息时,Angular 都会动态更新范围,并且在orderBy
应用过滤器之前的一瞬间,该新消息位于$scope.messages
. 这抛弃了我的ng-if
方法背后的逻辑,因此来自同一用户的每条新消息都显示了我想要隐藏的 HTML 元素(即它在方法上返回trueng-if
)。
根据console.logging
我的广泛介绍,在为 编译 HTML 时,索引为0ng-if
的消息仍然是发送的最后一条消息(不是最新消息)的第二个消息,而最新、最新的消息实际上是数组的最后一个索引。这会导致第一条语句生效,并为同一用户在同一天发送的每条新消息显示 HTML 元素(除非我刷新页面,其中所有内容都正确显示)。if
任何人都可以想到的解决方法?