Вопрос решил. Не знаю, насколько верно, но добился нужного мне результата.
Немного изменил свой цикл foreach(), теперь собираю попарно в массив не атрибуты моделей, а сами модели, при этом сохраняются все связи, которые мне нужны.
foreach($dataOne as $key => $value){
if($value->date_start == strtotime($data['FlightsSearch']['date_from'] . ' 00:00')){
$arr_from[] = $value;
}
if($value->date_end == strtotime($data['FlightsSearch']['date_to'] . ' 00:00')){
$arr_to[] = $value;
}
}
foreach($arr_from as $from){
foreach($arr_to as $to){
$arr_all[] = [$from, $to];
}
}
Для вывода результата в ListView сделал два представления, одно для результатов поиска "туда" и "обратно" и одно для результатов поиска в одну сторону
'itemView' => function($model, $key, $index, $widget) use ($search, $data, $arr_all){
if($data['FlightsSearch']['direction'] == 2) {
return $this->render('_item', ['model' => $model, 'search' => $search]);
}
if($data['FlightsSearch']['direction'] == 1) {
return $this->render('_item_to', ['model' => $arr_all, 'search' => $search]);
}
}
Теперь, когда пользователь ищет билеты "туда" и "обратно" подключается одни вид, если только "туда" - другой вид.
В первом случае это выглядит так:

Во втором так:

Может правильней было бы преопределить сам метод виджета, но...
В общем результат меня устраивает.
Благодарю все, кто пытался помочь в решении задачи.