Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [JQuery] Wytłumaczcie mi dlaczego to działa w ten sposób.
Forum PHP.pl > Forum > Po stronie przeglądarki > JavaScript
korro
Witam.
Robię dynamiczny formularz z użyciem JQuery.
Kod wygląda tak:
Szablon HTML:
  1. <textarea style="display:none" id="departments">
  2.    <tr id="departments_tr_{0}">
  3.        <td>{0}
  4.            <select name="departments_{0}">
  5.                <option value="">[choose department]</option>
  6.                <?php
  7.                $depts = $db->getDepartments();
  8.                foreach ($depts as $depts_row) {
  9.                    echo '<option value="'.$depts_row[0].'">'.$depts_row[1].'</option>'."\n";
  10.                }
  11.                ?>
  12.           </select>
  13.        </td>
  14.        <td>
  15.            <a href="#" ><img id="deleteDepartmentLine_{0}" border="0" src="images/minus.png"></a>
  16.        </td>
  17.   </tr>
  18. </textarea>


Niedziałający kod JS:
  1. <?php
  2. var templateDepartments = jQuery.format($("#departments").val());
  3.        var depts_id = 1;
  4.        function addDepartment() {
  5.            depts_id++;
  6.            $(templateDepartments(depts_id)).appendTo("#approvalLine tbody");
  7.            $("#deleteDepartmentLine_" + depts_id).click(function(){
  8.                $("#departments_tr_" +  depts_id).remove();
  9.            });
  10.          
  11.        }
  12.        $("#addDepartmentLine").click(addDepartment);
  13. ?>


Działający kod JS:
  1. <?php
  2. var templateDepartments = jQuery.format($("#departments").val());
  3.        var depts_id = 1;
  4.        function addDepartment() {
  5.            var r = depts_id++;
  6.            $(templateDepartments(r)).appendTo("#approvalLine tbody");
  7.            $("#deleteDepartmentLine_" + r).click(function(){
  8.                $("#departments_tr_" +  r).remove();
  9.            });
  10.          
  11.        }
  12.        $("#addDepartmentLine").click(addDepartment);
  13. ?>


Różnica polega na tym, że przepisuję zmienną i do zdarzeń używam przepisanej.
Pisząc 'nie działa' mam na myśli to, że wartość depts_id nie jest doklejana do nazwy elementu w momencie deklaracji, tylko w momencie zdarzenia.
Czyli: klikając na dowolny guzik minus usunie się tylko ostatnio wstawiony wiersz.

Z góry dzięki za pomysły.
erix
Zmienna utworzona z var wewnątrz funkcji, to zmienna lokalna.

Kod
$("#deleteDepartmentLine_" + r).click(function(){

Funkcja wywoływana z kontekstu click nie widzi zmiennej lokalnej dla funkcji; tylko globalne.
korro
Niezupełnie.
Ten przykład z var r działa w oczekiwany sposób.

W pierwszym przykładzie tak jak napisałem wcześniej.
Wygląda na to, że dla każdego
  1. <?php
  2. $("#departments_tr_" +  depts_id).remove();
  3. ?>
selektor jest równy maksymalnej wartości depts_id.
erix
O masz, zagapilem się:
Kod
depts_id = 1;
var r = depts_id++; //r = 1
depts_id //2

Postinkrementacja - najpierw jest zwracana wartość zmiennej, potem zwiększana. Gdybyś zrobił:
Kod
var r = ++depts_id;

wszystko będzie tak, jak chcesz.
korro
I znowu nie zupełnie.
Ta inkrementacja jest oczekiwana.
Indeks 1 przypada dla wiersza który jest jest już w tabeli approvalLine.
  1. <table id="approvalLine">
  2.                        <thead>
  3.                            <tr>
  4.                                <td>
  5.                                    <select name="departments_1">
  6.                                        <option value="">[choose department]</option>
  7.                                        <?php
  8.                                        $depts = $db->getDepartments();
  9.                                        foreach ($depts as $depts_row) {
  10.                                            echo '<option value="'.$depts_row[0].'">'.$depts_row[1].'</option>'."\n";
  11.                                        }
  12.                                        ?>
  13.                                   </select>
  14.                               </td>
  15.                               <td>
  16.                                    <a href="#" id="addDepartmentLine"><img border="0" src="images/plus.png"></a>
  17.                               </td>
  18.                            </tr>
  19.                        </thead>
  20.                        <tbody></tbody>
  21.                    </table>

Różni się od szablonu.

Przeanalizuj proszę całość.
dr_bonzo
Cytat(korro @ 17.03.2009, 19:40:55 ) *
Niezupełnie.
Ten przykład z var r działa w oczekiwany sposób.

W pierwszym przykładzie tak jak napisałem wcześniej.
Wygląda na to, że dla każdego
  1. <?php
  2. $("#departments_tr_" +  depts_id).remove();
  3. ?>
selektor jest równy maksymalnej wartości depts_id.


1. powcinaj kod prawidlowo - nie wprowadza wtedy tyle zamieszania
2.
  1. <?php
  2. var templateDepartments = jQuery.format($("#departments").val());
  3. var depts_id = 1; // zmienna globalna
  4. function addDepartment() {
  5.   depts_id++; // zmienna globalna
  6.   $(templateDepartments(depts_id)).appendTo("#approvalLine tbody");
  7.   $("#deleteDepartmentLine_" + depts_id).click(function(){
  8. // tworzysz fukcje == tworzy sie domkniecie, tzn 'depts_id' to to samo co zmienna globalna..
  9.       $("#departments_tr_" +  depts_id).remove(); // ... wartosc depts_id jest wczytywana w momencie wykonywania tej linijki
  10. // czyli dodasz kilka departametnow => depts_id bedzie powiedzmy 5, i depts_id wewnatrz tej funkcji odwoluje sie do tej samej zmiennej czyli tez ma wartosc 5
  11. // zrobienie: var r = depts_id wewnatrz addDepartment() tworzy zmienna lokalna, dalej: handler click() laczy sie znowu z ta zmienna, ale tym
  12. // razem ona jest lokalna i zostanie usunieta (wewnatrz handlera pozostanie nietknieta) wraz z koncem funkcji addDepartment(), jako ze nie
  13. // jest globalna i nigdzie indziej jej nie modyfikujesz to wszytko jest ok
  14.   });
  15.  
  16. }
  17. $("#addDepartmentLine").click(addDepartment);
  18. ?>
korro
Kod jest powcinany prawidłowo, forum zniekształca.

To jest odpowiedź.
Zdaje się, że to sposób myślenia z języków kompilowanych.
Dzięki.
dr_bonzo
Cytat
Kod jest powcinany prawidłowo, forum zniekształca.

Mozliwe..


Cytat
To jest odpowiedź.
Zdaje się, że to sposób myślenia z języków kompilowanych.
Dzięki.

No wlasnie dynamicznych, niekompilowanych, chociaz java i c# chyba maja wkrotce to miec smile.gif - javascript, ruby, hmmm nie znam innych.

I ciekawy link: uratowal mi skore kilka razy: http://bitstructures.com/2007/11/javascript-method-callbacks
I google: "closures javascript"
korro
Cytat(dr_bonzo @ 17.03.2009, 21:08:22 ) *
No wlasnie dynamicznych, niekompilowanych.

Chodziło mi o mój sposób myślenia.
Cytat(dr_bonzo @ 17.03.2009, 21:08:22 ) *
I ciekawy link: uratowal mi skore kilka razy: http://bitstructures.com/2007/11/javascript-method-callbacks
I google: "closures javascript"

Wielkie dzięki.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.