Отфильтруйте экземпляры "подмодели" из выпадающего списка
Я создал новое расширение Typo3 с помощью кикстартера.
и мой Cities
модель имеет несколько street
моделей.
В шаблоне street
модели из city
перечислены в выпадающем меню, как это:
Код шаблона:
<f:section name="main">
<h1>Single View for City</h1>
<f:flashMessages renderMode="div" />
<f:render partial="City/Properties" arguments="{city:city}" />
Filter:<br>
<a href='<f:uri.action controller="City" action="showFiltered" arguments="{city:city, char : 'a'}" />'>A</a>
<a href='<f:uri.action controller="City" action="showFiltered" arguments="{city:city, char : 'b'}" />'>B</a>
<a href='<f:uri.action controller="City" action="showFiltered" arguments="{city:city, char : 'c'}" />'>C</a>
<br>
<f:debug>{city}</f:debug>
<select onchange="location = this.options[this.selectedIndex].value;">
<option>Select street</option>
<f:for each="{city.streets}" as="street">
<option value='<f:uri.action controller="Street" action="show" arguments="{street : street}" />' >{street.name}</option>
</f:for>
</select>
<br>
<f:link.action action="list">Back to list</f:link.action><br />
<br>
<f:link.action action="new">New City</f:link.action>
</f:section>
Теперь мне нужно отфильтровать записи по их первому символу, используя ссылки над раскрывающимся списком.
(А, В, С).
Например, после нажатия A
только Aviation
а также Automation
будет показано...
Когда я выброшу city
я получаю это:
Но в не знаю, как получить доступ к улицам в моем showFiltered
действие:
public function showFilteredAction(\Vendor\CollectionPlan\Domain\Model\City $city) {
$char = $this->request->getArgument('char');
$this->view->assign('city', $city);
$this->view->assign('char', $char);
}
построить что-то вроде этого:
public function showFilteredAction(\ActiView\CollectionPlan\Domain\Model\City $city) {
$char = $this->request->getArgument('char');
/* This is pseudocode to demonstrate my idea */
foreach($city => street as $street){ /* Loop through the streets of the city model */
if(!$street => name.startsWith($char)){ /* Check if the streets name starts with the filter key */
$street.remove(); /* If it doesn't remove it from the city variable */
}
}
$this->view->assign('city', $city);
$this->view->assign('char', $char);
}
TL; DR
Как я могу получить доступ к улицам городской модели в своем действии контроллера, чтобы проверить, начинаются ли они с заданного ключа?
1 ответ
Каждое поле, к которому вы обращаетесь через точечную нотацию в контроллере флюидов, имеет геттер и сеттер (по крайней мере, если вы создали его с помощью Extension Builder), более того, вы не должны удалять улицу из коллекции, так как диспетчер постоянства удалит их, вместо этого добавьте в модель города переходный процесс с типом т.е. массива, давайте назовем его $streetsFilteredTransient
и создайте геттер, который будет фильтровать улицы:
Просто поместите это в модель вашего города и исправьте GeneralUtility::_GP
метод
/**
* The transient field in model is that which haven't a declaration
* in TCA and field in SQL file
* so it's ideal for *processing* other fields...
*
* @var array
*/
protected $streetsFilteredTransient = array();
/**
* Returns array of street objects which names begins with char,
* or all streets if no char is given
*
* @return array Array of objects
*/
public function getStreetsFilteredTransient() {
// As model has no access to request you need to fetch the `char` argument *manually*
$arguments = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('tx_flysites_show');
$char = (!is_null($arguments) && isset($arguments['char']))
? htmlspecialchars($arguments['char'])
: false;
foreach ($this->kinds as $street) {
if (!$char || $this->startsWith($street->getName(), $char))
$this->streetsFilteredTransient[] = $street;
}
return $this->streetsFilteredTransient;
}
private function startsWith($haystack, $needle) {
$haystack = strtolower($haystack);
$needle = strtolower($needle);
$length = strlen($needle);
return (substr($haystack, 0, $length) === $needle);
}
и использовать его в виде как:
<f:for each="{city.streetsFilteredTransient}" as="street">
...
</f:for>