Autor Zpráva
cantabrico
Profil
Caute páni, prípadne dámy. Viete mi prosím poradiť?

Mám script ktorý vyberie dáta z databázy a prevedie ich na spracovanie.

Všetko je OK, ale s tými dátami potrebujem neskôr v ďalšom skripte pracovať. Ale neviem, ako z tých premenných v prvom skripte, spravím globálne, aby som s nimi mohol pracovať. Keď zvolám var ešte pred začiatkom skriptu, tak to tam neskôr daný script nezapíše.

Viete mi pomôcť? Už som sa dočítal, že to nejak musím definovať ako globálnu premennú vnútri toho ajax scriptu. Ale ako?

<script id="source" language="javascript" type="text/javascript">    


  $(function testujem () 
{
//---------------------------
// 2) Send a http request with AJAX http://api.jquery.com/jQuery.ajax/
//---------------------------
$.ajax({                                      
  url: 'api.php',                  //the script to call to get data          
  data: "user=<?php echo $login_session; ?>",                        //you can insert url argumnets here to pass to api.php for example "id=5&parent=6"
  dataType: 'json',                //data format      
  success: function(data)          //on recieve of reply
  {
    var id1 = data[4];              //get id
    var vname = data[5];
    var vname2 = data[6];          //get name
    //--------------------------
    // 3) Update html content
    //--------------------------
    $('#output').html("<b>ID: </b>"+id1+"<b> Name: </b>"+vname+"<b> Name 2: </b>"+vname2 ); 
    $('#output2').html(id1);
    $('#output3').html(vname);     //Set output element html
    //recommend reading up on jquery selectors they are awesome http://api.jquery.com/category/selectors/
  setInterval( testujem, 2000); // všetko je OK

  }  

});

});  
</script>    
<div id="output2"></div> <!-- Sem zapíše výsledok OK , ale dáta sa nedajú iným skriptom ani vybrať. V konzole mi píše že id je prázdne-->    
<div id="output3"></div> <!--  Sem zapíše výsledok OK, ale dáta sa nedajú iným skriptom ani vybrať. V konzole mi píše že id je prázdne -->   


<script>
var id2 = id1; //var id2 aj id1 je prázdne, resp. nedefinované
var vnamee= vname; // 
.....
</script>      

api.php
....
             //--------------------------------------------------------------------------
  // 2) Query database for data
  //--------------------------------------------------------------------------
  $value = $_GET['user'];
  $result = mysql_query("SELECT * FROM $tableName WHERE tlc='$value'");            //query
  $array = mysql_fetch_row($result);                          //fetch result    

  //--------------------------------------------------------------------------
  // 3) echo result as json 
  //--------------------------------------------------------------------------
  echo json_encode($array);

?>
Dan Charousek
Profil
1) Nebylo by od věci si ošetřit vstupy uživatele do databáze pomocí escapovací funkce:
mysql_query("SELECT * FROM $tableName WHERE tlc='" . mysql_real_escape_string($value) . "'");
2) Princip je v tom, že běh scriptu nečeká na provedení nebo výslekdy ajaxové funkce a vesele se provádí dál, to znamená, že s jakýmikoliv daty, které získáváš ajaxovým voláním musíš pracovat v příslušné funkci ajaxu tzn. v tvém kódu na řádcích 15-26.
3) Další věc, která by zasloužila pozornost je fakt, že ve funkci testujeme nastavuješ interval, který volá onu funkci. Volání funkce se potom zrychluje:

function moje() {
    setInterval(moje, 1000);
}
moje();

provede se funkce, nastaví volání dané funkce po 1 sekundě.
Po sekundě se zavolá funkce znovu, nastaví se další interval, který volá funkci po sekundě, tudíž ti už běží 2.
Pokud chceš funkci opětovně volat po zpracování, správně bys měl IMHO použít setTimeout místo setInterval funkce.

Detailnější informace ti poskytnou zdejší, v javascriptu ostřílenější, kolegové :)
_es
Profil
cantabrico:
ale s tými dátami potrebujem neskôr v ďalšom skripte pracovať.
Je jedno, v akom „skripte“ je ktorá funkcia definovaná, zavolať ju môžeš rovnako, ako v tom istom „skripte“. (Pokiaľ myslíš skript v JS.)

Aby si s dátami mohol pracovať ihneď, ako sú dostupné, máš na to vo funkcii $.ajax jQuery knižnice vlastnosť prvého parametru succes (13. riadok), kde môžeš, vo funkcie do nej priradenej, s dátami, prístupnými z premennej data, pracovať ľubovoľne. Nepotrebuješ globálnu premennú, inú funkciu môžeš zavolať s argumentom, kde sú získané dáta.
cantabrico
Profil
Chlapi vďaka za odpovede, idem študovať a skúšať.

Re: Dan:
real escape .. vďaka. Mám to ošetrené pri prihlasovaní, tu ma to nenapadlo.
SetInterval - ďakujem, to ma nenapadlo že to takto funguje. Som sa aj čudoval, keď som otvoril konzolu, že mi to nejak divne odosiela dáta

Re: _es:
Áno mám na mysli js
cantabrico
Profil
No skúšal som čo ste poradili, ale som z toho tak trochu (viac) mimo. Ale niečo som vygooglil, a podarilo sa mi s polovice vyriešiť môj problém. Lenže stále je tu tá druhá polovica problému.
Ide o to, že z lokálnej premennej som spravil (asi)globálnu tým, ze som spred nej odstránil slovíčko var. V druhom skripte som ju definoval ako premennú slovom var. No ale druhy script už nedokáže vypočítať násobok týchto premenných. Dokážem to len ja v konzole.

Prečo nedokáže pracovať s údajmi? Kde robím chybu?

Opravené v prvom skripte
iddd = data[4];              //get id
vname = data[5];
vname2 = data[6]; 

Druhý script
<script> 
var iddd;
var vname;
var skuska = iddd * vname;
.
.
.
Konzola:


_es
Profil
cantabrico:
Prečo to nespravíš podľa rady v [#3]? Tie spomínané funkcie máš kde?
„Zhruba“ asi z [#1]:
...
success: function(data){Tu budeš pracovať s premennou data, môžeš aj zavolať inú funkciu ináFunkcia(data)}
...
Dan Charousek
Profil
Dan Charousek:
s jakýmikoliv daty, které získáváš ajaxovým voláním MUSÍŠ pracovat v příslušné funkci ajaxu tzn. v tvém kódu na řádcích 15-26.
To je stěžejní informace, ze které musíš vycházet.
cantabrico
Profil
Ide o to, že prvý skript mi vytiahne dáta z databázy, a druhý skript je na mapy, aby tam ukázal polohu obchodu, domu, užívateľa, hocčoho ... Lenže sa mi to žiadnym spôsobom nepodarilo implementovať do tej ajaxovej funkcie.
Keď vopchám tú mapovú funkciu za setTimeout, alebo pred to, alebo akokoľvek, tak to nefunguje. Ani keď dám natvrdo dáta na pozíciu, tak nenačíta mapu. Predpokladám, že script na mapu musí byť v samostatnom skripte. Preto tam potrebujem načítať nejaké dáta z databázy.
Nakopírovaný je od riadku 25 - 41.

V čom je chyba? Alebo, viete mi poradiť iný script na výber dát aby ich uložilo do globálnej premennej?

<script id="source" language="javascript" type="text/javascript">

  $(function testujem () 
  {
    //-------------------------------------------------------------------------------------------
    // 2) Send a http request with AJAX http://api.jquery.com/jQuery.ajax/
    //-------------------------------------------------------------------------------------------
    $.ajax({                                      
      url: 'api.php',                  //the script to call to get data          
      data: "usertc=<?php echo $login_session; ?>",                        //you can insert url argumnets here to pass to api.php for example "id=5&parent=6"
      dataType: 'json',                //data format      
      success: function(data)          //on recieve of reply
      { 
        iddd = data[4];              //get id
        vname = data[5];
        vname2 = data[6];          //get name
        //--------------------------------------------------------------------------------------
        // 3) Update html content
        //--------------------------------------------------------------------------------------
        $('#output').html("<b>lat: </b>"+iddd+"<b> lon: </b>"+vname+"<b> alt: </b>"+vname2 ); 
        $('#output2').html(iddd);
        $('#output3').html(vname);     //Set output element html
        //recommend reading up on jquery selectors they are awesome http://api.jquery.com/category/selectors/
      setTimeout( testujem, 2000);
      function initialize() {

  var myLatlng = new google.maps.LatLng(55,55);
  var mapOptions = {
    zoom: 3,
    center: myLatlng
  }
  var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);

  var marker = new google.maps.Marker({
      position: myLatlng,
      map: map,
      title: 'Tu je!'
  });
}

google.maps.event.addDomListener(window, 'load', initialize);
      }  
            
    });
    
  }); 

  </script>
_es
Profil
cantabrico:
A setTimeout tam máš na čo?
Ako ti už radil aj Dan Charousek:
...
success: function(data)
{
Tu daj všetok kód, kde chceš s tými vrátenými dátami niečo robiť.
}
...
Dan Charousek
Profil
Nechci se prohrabávat tím kódem, ale zkusím ti nastínit, jak by to mělo vypadat.

var aktualizujMapu(data) {

    // instance nějaké google api
        // zpracování dat z ajaxu
    
}

var ajaxCall = function() {

    $.ajax({
        // nastavení jako je url, data atd.
        success: function(data) {
            aktualizujMapu(data);
        }
    });
    
    setTimeout(ajaxCall, 2000);
    
}
// první volání funkce
ajaxCall();
1Pupik1989
Profil
Pokud potom budeš volat víc funkcí, tak asi nemá smysl výstup předávat jako parametr. Ulož výstup do globální proměnné a pak ho ve funkcích čti.

Vykonávat vše v callbacku taky není ideální. Pak se kód strašně rozvětví a je nečitelný. Jako hodnotu metodě "success" předej předdefinovanou funkci. Pak už tomu přijdeš na kloub.

Celý princip je v tom, že asynchronní má vždy odezvu. Tím pádem se následující kód vykoná dřív. Jedna možnost je synchronní volání (pokud načítáš na začátku nezbytný soubor) nebo tzv. callback (což je funkce, která se vyvolá po akci, příklad jsou události). Třeba takový onclick taky neví co budeš dělat, dokud ho nevyvoláš. Ten samý princip je ajax.
_es
Profil
1Pupik1989:
Ulož výstup do globální proměnné a pak ho ve funkcích čti.
To nie je správny postup v programovaní - nahradzovať komunikáciu s funkciou cez argumenty funkcie premennými mimo funkcie. Potom nie je isté, čo všetko môže také premenné meniť. Napríklad neskorší sieťový požiadavok môže vrátiť dáta aj skôr ako skorší. Potom by sa pracovalo s nesprávnymi dátami.

Vykonávat vše v callbacku taky není ideální. ... Jako hodnotu metodě "success" předej předdefinovanou funkci. Pak už tomu přijdeš na kloub.
To je predsa stále skoro to isté. Či priradí ...success:function(argumenty){nejaký kód} alebo ...success:názovFunkcie. Podstatné je si uvedomiť, že sa spustí funkcia tam priradená, (skoro) jedno kde definovaná.
1Pupik1989
Profil
_es: Nic jiného nebude mít přístup k proměnné kromě těch funkcí vyvolaných v callbacku. Tudíž nemůže nastat žádná vyjímka.
_es
Profil
[#13] 1Pupik1989:
Nerozumiem, „Ulož výstup do globální proměnné“ - do tej má predsa prístup všetko. Okrem toho, prístup k premennej závisí od toho, kde bola funkcia definovaná a nie kde bola „vyvolaná“.
Dan Charousek
Profil
_es:
do tej má predsa prístup všetko
Jenže než se data z ajaxového volání do těchto proměnných uloží budou se dávno zpracovávat funkce, které se s nimi budou snažit pracovat a v tu chvíli budou ještě prázdné.
_es
Profil
[#15] Dan Charousek:
Lenže môže byť ten kód všelijako upravovaný, rozširovaný... Napríklad niekoho napadne, že s tými dátami trebárs za 10 sekúnd ešte niečo spraví. Pritom tam však už môžu byť dáta z iného „AJAXového volania“, keďže niekoho napadlo si dáta medzi rôznymi funkciami vymieňať navrhnutým nevhodným spôsobom. Po prvom vrátení dát v tej premennej nebudú nejaké „prázdne“ dáta, ale dáta z „nejakého“ AJAXového volania.
Dan Charousek
Profil
[#16] _es
Můžeš uvést konkrétní příklad?
Nenapadá mě rozumný důvod pracovat s daty jindy (a jinou funkcí) než po jejich získání ajaxovým voláním. Pokud volá AJAX periodicky každé 2 sekundy data jsou každou 3. skundu jiná. Proč by nějaká externí funkce chtěla pracovat s takto nestálými daty?

Napríklad niekoho napadne, že s tými dátami trebárs za 10 sekúnd ešte niečo spraví
V tomhle případě by se 5x změnily hodnoty těch proměnných.

Nelíbí se mi to a akorát si tak člověk může zadělat na těžkoodhalitelné chyby.
1Pupik1989
Profil
Je to lehce rizikovější, hodí se to spíše u objektů, kde se v callbacku přiřadí do vlastnosti data vrácená Ajaxem a nějakým způsobem se zpracovávají dál. Čili zavolám třeba metodu objektu.

Nicméně se mi nikdy nevymstilo přiřazování vrácených dat ajaxu do globální proměnné. Pokud znovu pošlu požadavek na server, tak to většinou znamená, že stará data v té globální proměnné už nepotřebuji. Nenapadá mě žádný příklad u kterého by se něco pokazilo. Pokud _es má, tak přiznám chybu.
Keeehi
Profil
1Pupik1989:
Jde o to, že špiníš globální prostor nad kterým nemáš absolutní kontrolu. Pokud bys pak použil třeba nějakou knihovnu třetí strany, která by byla napsaná stejným přístupem jako máš ty, může se klidně stát, že si budete vzájemně přepisovat data v globální proměnné. I když se třeba v tomto konkrétním případě nic nestane, není to dobrý návyk.
_es
Profil
Dan Charousek:
Nie som si celkom istý, či mi oponuješ alebo so mnou súhlasíš. Išlo o 1Pupik1989ov návrh, že sa majú vrátené dáta z AJAXu uložiť do globálnej premennej a až z nej inde čítať.

1Pupik1989:
Je to lehce rizikovější
Akurát že nie len „ľahko“ rizikovejšie.

Nenapadá mě žádný příklad u kterého by se něco pokazilo.
V AJAXe často ide aj o to, aby boli výstupné dáta „spárované“ s konkrétnym AJAXovým volaním a vstupmi, takže ak to bude v aplikácii treba, tak sa to môže pokaziť veľmi ľahko. V AJAXe môže byť aj viac sieťových požiadavkov naraz, či aj v presne nedefinovanom čase. Alebo stačí to, aby bola použitá ešte aj iná „medzifunkciová komunikácia“ a s rovnako nazvanou premennou. Alebo nejaký iný skript použije rovnako nazvanú premennú na iný účel. Taká komunikácia sa nedá použiť na „komunikáciu“ medzi rôznymi oknami/rámcami.
Okrem toho, prístup k lokálnym premenným môže byť o čosi rýchlejší než ku globálnym - vzhľadom na iné veci často zanedbateľné - no nemusí to platiť vždy.
1Pupik1989
Profil
_es: Pokud očekáváš, že ti někdo dokáže přepsat proměnnou, tak jsi v pytli. Může ti klidně přepsat funkci nebo i objekt. Jak se proti tomu obrníš? To prostě nejde. Čili to znamená, že nikdy nemůžeš mít v globálním prostoru nic, aby to nebylo přepisovatelné. Žádné "call only" v javascriptu není. I kdyż všechno schováš do closure, tak nebudeš mít nikdy klid, protože i to půjde přepsat. Všechno jde přepsat! Máš na to nějaký fígl? Pokud ano, tak se rád poučím.


Já vím, że je to kravina a užívám to jen v nejnutnějším případě a mám jistotu, co v té proměnné je to co chci. Ale jak jsem psal, tak většinou to objektu přiřadím jaki vstup.

Ve směs prostě chci, aby se tento problém rozvedl a definitivně se řeklo proć je to špatné. Vím, že jsem to mohl napsat v mém prvním příspěvku, ale to by nebylo ono. Já proti té teorii nejsem.
Dan Charousek
Profil
_es:
Nie som si celkom istý, či mi oponuješ
Omlouvám se, blbě jsem pochopil tvoji reakci. V tom případě věnuji [#17] Dan Charousek 1Pupik1989, 1Pupikovi1989

Dodatek k [#21]: Nikdo netvrdí, že je to obrana proti přepisování nějakých proměnných či funkcí. Když se někdo rozhodně ti přepsat funkci, tak s tím nic neuděláš. Je to jen způsob jak předejít k nechtěným kolizím v kódu. Porušuje to zapouzdřenost funkce, která by měla pracovat s okolním světem jen skrze parametry a návratovou hodnotu.
cantabrico
Profil
[#9] _es
SetTimeout tam mám na skúšku. Chcem vedieť či funkcia prijíma dáta, a či vie s nimi pracovať. Ale nevie. kľudne tam môžem mať aj 10 minútový interval, ale aby som videl výsledok a mohol s ním pracovať, je vhodné to testovať s krátkym časom.
Skúšal som to, ale nech som tú funkciu dal akokoľvek tak mi to nešlo. Skúšal som na rôzne miesta a ani za... mi to nešlo. Teda, rád by som to tam dal, ale nefunguje to :-(. Ani keď om odstránil setTimeout.

[#10] Dan Charousek
Vďaka. Skúšal som aj toto, ale nespojaznil som to. Ale určite sa k tomuto návrhu vrátim, nakoľko mi prijde veľmi logický.

[#11] 1Pupik1989
Skúšal som ale nejak som z toho blazon. Ale všetky navrhy si priebežne prechadzam, a skúšam nanovo. Fakt si cenním každú radu. Niektorým veciam chápem viac než na začiatku.
A v podstate mi o to ide. uložiť to do globalnej premennej. Lenže neviem ako. Preto som pisal. Lebo tento script ajaxovy je jediny ktory mam na vyber dat z databazy. O inom neviem. A hľadal som všade. Len som si ich buď nevedel upraviť (ak išlo o tie ktoré si vyžadovali napr. klik), alebo už ani neviem prečo mi nič nefungovalo, resp. či som vôbec nejaký na výber dát z databázy našiel.

No, ale skúšal som hľadať aj iné API a narazil som na asynchrónny script. No a tomuto tiež nechápem. Ten asynchrónny si vie dáta vytiahnuť z premennej, ale ten pôvodný script nie. (všetko z google api). Prečo? Však skriptu môže byť jedno ako dáta zapíšem do premennej, on si ich má len prečítať nie? A prečo synchrónny (pôvodný) script to nedokáže, a nový asynchrónny áno aj napriek tomu že nieje vnorený vo funkcii v ktorej vyťahujem dáta z databázy? Alebo si tie dáta neťahá z premennej ale z "neviemodkiaľ"?

 <script>
function initialize() {
  var mapOptions = {
    zoom: 8,
    center: new google.maps.LatLng(-34.397, 150.644)
  };

  var map = new google.maps.Map(document.getElementById('map-canvas'),
      mapOptions);
}

function loadScript() {
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp' +
      '&signed_in=true&callback=initialize';
  document.body.appendChild(script);
}

window.onload = loadScript;

    </script>
_es
Profil
cantabrico:
A v podstate mi o to ide. uložiť to do globalnej premennej.
Nie o to naozaj „nejde“, ak potrebuješ pracovať v inej funkcii s vrátenými dátami, tak ti ju treba len zavolať v tvare:
názovFunkcie(data); kde data je premenná s vrátenými dátami a funkciu definovať ako function názovFunkcie(data){nejaký kód pracujúci s premennou data} pričom je jedno, kde (v akom skripte) je funkcia definovaná.

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: