Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
tomas
Člen
Avatar
tomas:23.4.2023 15:53

Ahoj všem, řeším problém s načtením dat z DB. Mám jednoduchý AJAX dotaz, který mě vrátí správné data ve formátu JSON objektu. Já bych ale potřeboval tento vystup zachovat na stránce a následně s ním pracovat. Ale nedaří se mě to.

Má třída:

class CastStroje{

        constructor() {
            this.listCastStroje = [];
            this.a;
            this.b;
       }
        load(){
                 $.ajax({
                        type: "GET",
                        url: "/api/cast_stroje",
                        dataType: 'json',
                        async: false,
                        contentType: "application/json; charset=UTF-8",
                        success: function (data) {
                                // funguje
                                this.a = data[0].castStroje;

                                this.listCastStroje = data;

                                // funguje
                                this.b = this.listCastStroje[0].castStroje
                        }
                });
        }

        const castStroje = new CastStroje();
        castStroje.load();
        let test_a = castStroje.a; // nefunguje
        let test_b = castStroje.a; // nefunguje
        let test_c = castStroje.listCastStroje[2].castStroje; // error listCastStroje is undefine

Zkusil jsem: Když jsem zkoušel pustit kód, tak do proměnné "a" ki "b" dostanu hodnotu, ale při volání jsou prázdné. Zkoušel jsem i prostě jen vrátit data (return data) a stejně mě to nic nevrátilo, přitom promněnná data je naplněná a seznam obsahuje.

Chci docílit: Chci dosáhnout toho, abych po načtení dat, mohl pracovat s listem částí stroje. Ten list obsahuje stromovou strukturu částí stroje a já jím plním tři select boxy. Chci tedy naplnit první selekt box a na základě toho ci v něm bude vybraný naplnit druhý box a pak třetí. k tomu potřebuji, abych měl obsah promněnné naplněný. Nechci to řešit třemi dotazi do DB, ale proste si to cyklem vyberu z této promněnné. Problém je ten, že jakmile načtu ty data, tak nejsou obsaženné v promněnní listCastStroje, čili je nemůžu procházet a pracovat s nimi. Jak se to dá elegantně řešit? Součástí té třídy budou i mětody, které mě budou select boxy plnit.

 
Odpovědět
23.4.2023 15:53
Avatar
tomas
Člen
Avatar
tomas:23.4.2023 16:35

Ještě jsem zkusil vytvořit třídu item.

class castStrojeItem {
        constructor(castStroje, id, id_Parent) {
            this.castStroje;
            this.id;
            this.id_Parent;
        }
    }

v třídě castStroje jsem přidal do construktoru inicializaci proměnné this.csList = []; a pak jsem ji chtěl naplnit při načtení dat ajaxem.

success: function (data) {
       $.each(data, function (idx, obj) {

       const item = new castStrojeItem(obj.castStroje, obj.id, obj.id_Parent);
       this.csList.push(item); // error this.csList is undefined
});

Jako učím se a zkouším si objektové programování v javascriptu, bez objektů bych to udělal jinak, ale tohle se chci naučit. Proč mě píše, že je undefined? když vytvořím instanci objectu castStroje, tak ji přece konstruktor inicializuje na prázdné pole, nebo se pletu?

 
Nahoru Odpovědět
23.4.2023 16:35
Avatar
tomas
Člen
Avatar
tomas:23.4.2023 16:45

Tak jsem na to asi přišel, v části success ajaxového dotazu prostě není vlastnost this.csList dostupná. musel jsem si přidat locální promněnou a to po skončení axaxu vložit do this.scList.

let list = [];
                $.ajax({
                        type: "GET",
                        url: "/api/cast_stroje",
                        dataType: 'json',
                async: false,
                        contentType: "application/json; charset=UTF-8",
                        success: function (data) {
                    $.each(data, function (idx, obj) {

                        const item = new castStrojeItem(obj.castStroje, obj.id, obj.id_Parent);
                        list.push(item);
                    });
                        }
                });
            this.csList = list;
        }

Jestli je tohle správný postup netuším, ale funguje mě to.

 
Nahoru Odpovědět
23.4.2023 16:45
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:24.4.2023 10:11

Je to mozny zpusob. Problemu muze byt vic. Treba u asyn provozu je nutne pochopit postupne nacitani a callback funkce. Ve vem pripade je problem v tom, ze vnoreny objekt je uplne jiny objekt. Ja bych si to treba napsal spis takto, abych oddelil cast, kterou resi ajax a kterou jiny program

                $.ajax({
                        type: "GET",
                        url: "/api/cast_stroje",
                        dataType: 'json',
//                        async: false,
                        async: true,
                        contentType: "application/json; charset=UTF-8",
                        success: mycallback;
                    });
function mycallback (data) {
                    let list = [];
                    $.each(data, function (idx, obj) {

                        const item = new castStrojeItem(obj.castStroje, obj.id, obj.id_Parent);
                        list.push(item);
                    });
                    zobraz(list);

k tomu prvnimu kodu, volas ajax jako externi funkci jineho objektu. This je pro nej objekt jquery.

$ = new jquery();
...
                 $.ajax({
                        type: "GET",
                        url: "/api/cast_stroje",
                        dataType: 'json',
                        async: false,
                        contentType: "application/json; charset=UTF-8",
                        success: function (data) {
                                this.a = data[0].castStroje; // this = $ !!!
                                this.listCastStroje = data;
                                this.b = this.listCastStroje[0].castStroje
                        }
//Samozrejme, ze to unvitr funguje, pac je to toez, jako napsat
                                $.a = data[0].castStroje;
                                $.listCastStroje = data;
                                $.b = $.listCastStroje[0].castStroje
// aby ti to spravne fungovalo, musel bys pouzit pomocnou promenou, obvykle that

class castStrojeItem {
   let that = this;
                 $.ajax({
                        type: "GET",
                        url: "/api/cast_stroje",
                        dataType: 'json',
                        async: false,
                        contentType: "application/json; charset=UTF-8",
                        success: function (data) {
                                that.a = data[0].castStroje;
                                that.listCastStroje = data;
                                that.b = this.listCastStroje[0].castStroje
                        }

Nebo, zkusim to napsat jeste jinak.

a = {list:[],
       myajax: function(str) {
             alert(this); alert(this.list); alert(this.out); alert(str) // out ti vypise undefined
       }};
b = {out: [],
       load: function {
            a.myajax()
       }}
b.load();
 
Nahoru Odpovědět
24.4.2023 10:11
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:24.4.2023 10:20

Jeste na to existuje nejaka jedna finticka, kterou nepouzivam, bindovani nebo tak neco. Ale, ted to nemuzu najit. Treba to sem nekdo napise. Je to ve smyslu, ze na na objekt pripojis jiny ojekt a pak je this jako this toho objektu. Ale, nejsem si jisty, jestli se to tak jmenuje. Pouziva se to spis pro casovace.

const module = {
  x: 42,
  getX: function() {
    return this.x;
  }
};

const unboundGetX = module.getX;
console.log(unboundGetX()); // The function gets invoked at the global scope
// Expected output: undefined

const boundGetX = unboundGetX.bind(module);
console.log(boundGetX());
// Expected output: 42

---

class LateBloomer {
  constructor() {
    this.petalCount = Math.floor(Math.random() * 12) + 1;
  }
  bloom() {
    // Declare bloom after a delay of 1 second
    setTimeout(this.declare.bind(this), 1000);
  }
  declare() {
    console.log(`I am a beautiful flower with ${this.petalCount} petals!`);
  }
}

const flower = new LateBloomer();
flower.bloom();
// After 1 second, calls 'flower.declare()'

https://developer.mozilla.org/…unction/bind

 
Nahoru Odpovědět
24.4.2023 10:20
Avatar
tomas
Člen
Avatar
tomas:24.4.2023 17:55

Díky.

 
Nahoru Odpovědět
24.4.2023 17:55
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 6 zpráv z 6.