Předání dat komponentě pro vykreslení markeru na mapě

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
house23
Člen | 17
+
0
-

Ahoj všichni, řeším následující prekérku. Píšu web kde je hlavní strana s formulářem. V té se nastaví vyhledávání a přesměruje na další stranu s výsledky hledání. Implementuju to tak že si pošlu do Search presenteru(výsledky hledání) jako parametry nastavení toho vyhledávání.

V tom search presenteru provedu databázový dotaz a výsledek si pošlu do šablony. Výsledky hledání se zobrazují jak v seznamu pod sebou tak jako markery na mapě. Pro vyobrazení markerů používám komponentu od @Oli a bezproblému mi funguje, potíž je v tom jak ji dynamicky předávat data pro vykreslení.

Zkoušel jsem persistentní parametry které fungovaly, ale ty mi způsobují že mi pak nefunguje ajax v závislém selectboxu.

V současném řešení si vytvořím třídní proměnnou pro objekt s markery a v pomocné metodě je vytvořím. Podle debugování se vše správně uloží, ovšem na mapě se markery nezobrazí. Metodu pro přidáni markeru do komponenty volám v renderDefault a obávám se že komponenta se vykresluje ještě před renderDefault, proto se mi na mapě nic nezobrazí. Když zkusím použít v renderDefault metodu pro invalidováni markerů tak dostanu chybu Component '' is not attached to ‚Nette\Application\UI\Presenter‘.

Komponentu vytvářím pomocí createComponent…

Někdo nějaké nápady?

David Matějka
Moderator | 6445
+
0
-

Muzes ukazat kod?

house23
Člen | 17
+
0
-

Vytvořím si v konstruktoru objekty a uložím instance do třídních proměnných

public function __construct(Nette\Database\Context $database,\Oli\GoogleAPI\IMapAPI $mapApi, \Oli\GoogleAPI\IMarkers $markers)
    {
        $this->database = $database;
        $this->map = $mapApi->create();
        $this->markers = $markers->create();
    }

Tady přidávám markery

 public function setMarkers($productsSelect){

        foreach($productsSelect as $product) {
            $coordJson = $product->coords;
            $coordObject  = json_decode($coordJson);
            $lat = $coordObject->coordinates[0];
            $lng = $coordObject->coordinates[1];
//            dump($lat);
//            dump($lng);
            $newMarker = $this->markers->addMarker(array($lng, $lat), false, null);
            $newMarker->setMessage($product->product_title);
//            dump($newMarker->markers[0]);

        }

        $this->map->addMarkers($this->markers);
//        $this->map->invalidateMarkers();

    }

Vytvoření komponenty GoogleMap

protected function createComponentGoogleMap()
{
    $this->markers->isMarkerClusterer();  // neer markers group to one cluster
    $this->markers->fitBounds();  // zoom as mutch as possible, but every marker will be displaied
    $this->markers->setColor('red');  // Can set color of markers to 10 diferent colors
    $this->markers->setDefaultIconPath('img/');   // Path which will be prepend icon path
    $this->map->addMarkers($this->markers);
    return $this->map;
}

Voláni setMarkers v renderDefault

public function renderDefault()
    {
        $this->template->_form = $this['searchForm'];
        $values = $this->getParameters();

            if ($values['SubcategoryID'] == 0) {
                $categoryID = $values['CategoryID'];
            } else {
                $categoryID = $values['SubcategoryID'];
            }
            $productsSelect = $this->search->searchProducts($categoryID, $values['range'], $values['lat'], $values['lng']);

            $this->setMarkers($productsSelect);

//            $this->template->productsSelect = $productsSelect;

    }
Oli
Člen | 1215
+
0
-

Budeš to muset vyzkoušet. V nové verzi mapy jsem to ještě nepotřeboval. Ve starší verzi stačilo víceméně zavolat tuhle funkci. V jedné starší aplikaci jsem to dělal zhruba takhle:

public function handleFilterMarkers(array $filter = null)
{
	// Najdou se relevantní budovy
	if (count($filter)>0)
	{
		$filter = $this->prepareDataForFilter($filter);
		// všechny budovy na základě hledaných tagů
		$itemsArr = $this->buildingModel->getFilteredBuildings($filter);
	} else
	{
		// všechny aktivní budovy
		$itemsArr = $this->buildingModel->getActiveRows();
	}

	$markers = $this->markers;
	// Pokud existují nějaké markery tak se všechny smažou a načtou se nový
	if ($itemsArr)
	{
		$markers->deleteMarkers();
		$markers = $this->addMarkers($itemsArr, $markers);

		$this->sendResponse(new \Nette\Application\Responses\JsonResponse($markers->getMarkers()));
	}
}

V šabloně potom takhle

$(function(){
	$('#frm-filter-form').on( "click", '#frmform-send', function(e) {
		var url = {link FilterMarkers! array(1,2,3,4), };
		var author = $('#frmform-author').val();
		var country = $('#frmform-country').val();
		var year = $('#frmform-year').val();
		var type = $('#frmform-type').val();

		if (!author && !country && !year && !type)
		{
			url = {link FilterMarkers!};
		} else
		{
			url = url.replace('filter%5B0%5D=1', 'filter%5B0%5D='+author);
			url = url.replace('filter%5B1%5D=2', 'filter%5B1%5D='+country);
			url = url.replace('filter%5B2%5D=3', 'filter%5B2%5D='+year);
			url = url.replace('filter%5B3%5D=4', 'filter%5B3%5D='+type);
		}
		loadMarkers(decodeURIComponent(url));

		e.preventDefault();
	});
});

Je to hodně kostrbatý, ale tenkrát to muselo být rychle a pořád mě to nešlo…

Jak to potom vypadá můžeš vidět na http://www.ex-centric.eu/cs/mapa/


V nové mapě by teoreticky mohlo stačit místo loadMarkers refresnout načtení mapy

Nebo možná jen map.loadMarkers(). Budeš to muset vyzkoušet. Jestli se ti to nějak povede v tý nový mapě, mohl by jsi prosím někam nahrát postup? Mohlo by se to hodit ostatním, případně bych to dal do dokumentace.

Díky