Yii: MTreeView extension - расширение для формирования древовидного меню + немножко loco-магии

Yii: MTreeView extension - расширение для формирования древовидного меню + немножко loco-магии Настраиваем ajax подгрузку данных в древовидный список, формируемый MTreeView

Секрет волшебства в объединении: Yii + MTreeView extension + вычисляемые поля MySQL.

Скачиваю и устанавливаю расширение MTreeView, рекомендую установить и посмотреть пример использования этого расширения (готовое приложение, где сразу видно как вызывать MTreeView).

Вызываю в виде (в шаблоне):

$this->widget('application.extensions.MTreeView.MTreeView',
			array('url'=>array('ajaxFillTree'),
				'animated'=>'fast',
				'collapsed'=>true,
			)
		);

Это случай, где будем формировать Ajax подгрузку данных во второй уровень древовидной структуры. Это приходится делать из-за url - в корневом уровне дерева ссылки идут одного вида (страны), а вложенные элементы имеют другой вид (ссылаются на города). Вызываем действие ajaxFillTree, которое описано в контроллере (у меня в основном контроллере SiteController).

Непреодолимое желание сделать это (можно сравнить с тем, как парень добивается свидания с понравившейся девушкой) привело к нахождению волшебного решения: формирование url происходит одним запросом к базе данных (причём и страны и города хранятся в одной таблице, потому что Денис так захотел), при этом на лету узнаётся с чем мы имеем дело - со страной или городом, и соответственно, исходя из этого формируется необходимый вид ссылки.

 

Yii: MTreeView extension - расширение для формирования древовидного меню + немножко loco-магии

 

В контроллере видим всю магию:

public function actionajaxFillTree(){
		Yii::import('application.extensions.MTreeView.MTreeView');
	    if (!Yii::app()->request->isAjaxRequest) {
		    exit();
	    }
	    $countryId = "0";
	    if (isset($_GET['root']) && $_GET['root'] !== 'source') {
		    $countryId = (int) $_GET['root'];
	    }
	    
	    if($countryId === '0') 
				{$url = '/countriesandcities/country/';}
				else
				{$url = '/countriesandcities/city/';}
	    
	    $sql = "SELECT m1.id, m1.name AS text, m2.id IS NOT NULL AS hasChildren, CONCAT('$url', m1.alias) AS url "
	    . "FROM tbl_countries_cities AS m1 LEFT JOIN tbl_countries_cities AS m2 ON m1.id=m2.country_id "
	    . "WHERE m1.country_id <=> $countryId "
	    . "GROUP BY m1.id ORDER BY m1.name ASC";
	    $req = Yii::app()->db->createCommand($sql);
	    $children = $req->queryAll();

	    echo str_replace(
		    '"hasChildren":"0"',
		    '"hasChildren":false',
		    MTreeView::saveDataAsJson($children)
	    );
	    exit();
	}

Здесь интересен SQL-запрос. m1 и m2 - это таблицы (в нашем случае это одна и та же таблица tbl_countries_cities). В ней вычисляемое поле 'url' формируется конкатенацией переменной $url (разной для типов - города и страны) и поля из базы - 'alias'. 'country_id' = 0 соответствует случаю, когда запись является страной, то есть по задумке то, что имеет нулевую страну, то и является страной. Город принадлежит какой-либо стране, соответственно имеет 'country_id' отличный от нуля.

Рабочий пример смотрите на нашем сайте - Зачем путешествовать? (whytravel.ru)

 

 

 

Источник: loco.ru

almix
Разработчик Loco, автор статей по веб-разработке на Yii, CodeIgniter, MODx и прочих инструментах. Создатель Team Sense.

Вы можете почитать все статьи от almix'а.



Другие статьи по этой теме:

Комментарии (0)     Подпишитесь на RSS комментариев к этой статье.