Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailemVyřešeno [JS, jQuery, AngularJS] prebliknutie pri načitávaní

Zdravím,

potrebujem poradiť s problémom:

index.html:


<body data-ng-app="app" data-ng-cloak="">
    ...
    <div data-ng-view=""></div>
    ...
</body>

view.html:


    ...
    <span data-ng-bind="vysledok"></span>
    text ktorý preblikne
    ...
    <span data-ng-bind="vysledok2"></span>
    ďalší text ktorý preblikne
    ...

app.js:


/* routing */
...
$routeProvider.when('/mojaurl',  {
    templateUrl: 'view.html',
    controller: 'myctrl'
})
...

...
app.controller('myctrl', function($scope) {
    $scope.vysledok = ... ;
    ...
    ...
    $scope.vysledok2 = ... ;
}

jak môžem tomu preblikávaniu zabrániť? Zatial som to riešil spôsobom že som mal skrz CSS skrytý obsah ktorý preblikával a potom skrz jQuery .show() som ho zobrazil, ale když je toho obsahu tucet rôznak zanestovaný a propletený obsahom ktorý sa binduje tak je to problém. Veľkosť elementov nemôžem nastaviť napevno lebo neviem aký bude ich obsah kým to nenabindujem.

Jsou zobrazeny jen nové odpovědi. Zobrazit všechny
Předmět Autor Datum
Co tohle?
Pavel 02.10.2018 20:44
Pavel
problém vidím asi v tomto: [qamRKkx.png] tretí a paty riadok v screenshote sú súbory s dátami ktor…
Mlocik97 02.10.2018 20:54
Mlocik97
Co teda to obejít takto? Při spuštění aplikace (načtení webu) se zobrazí jen prázdná stránka (nebo s…
Pavel 02.10.2018 21:14
Pavel
skusil som to ešte trocha iným spôsobom, ktorý funguje tak trocha opačne, pri bežnom načitávaní to f…
Mlocik97 02.10.2018 21:19
Mlocik97
Tak teď už ti vůbec nerozumím.
Pavel 02.10.2018 21:23
Pavel
Predstav si takú situáciu že pôvodne sa mi to načitávalo takto (hviezdička predstavuje začiatok riad…
Mlocik97 02.10.2018 21:30
Mlocik97
Jo, už chápu. Zkus teda prvně zobrazit prázdnou stránku a po načtení dat z AJAX volání přes routerPr…
Pavel 02.10.2018 21:40
Pavel
No jasně že má!
Pavel 02.10.2018 21:43
Pavel
pozerám toto by mohlo byť asi najlepšie riešenie. nový
Mlocik97 02.10.2018 21:58
Mlocik97
tak to nechápem, ale i s týmto kódom: resolve: { app: function($q) { var defer = $q.defer(); defer… poslední
Mlocik97 02.10.2018 22:21
Mlocik97
<span ng-if="loaded && step > 0">Tohle jako první</span><span ng-if="loaded && step > 1">Tohle jako…
Pavel 02.10.2018 21:29
Pavel
Dík, skúsil som to a funguje to. Akurát mi to prijde trocha nepraktické. To už pak neni lepšie volať…
Mlocik97 02.10.2018 21:39
Mlocik97
Myslím že tá premenná counter pak zbytočne bere výkon i zaberá RAM protože mám o premennú navyše. T…
Pavel 02.10.2018 21:41
Pavel
Tak som to nakoniec vyriešil ešte úplne inak, riešením ktoré sa mi docela páči. Postupnosť načitáva…
Mlocik97 02.10.2018 21:50
Mlocik97
A můžeš sem to řešení vložit? Díky.
Pavel 02.10.2018 21:52
Pavel
.then(function() { $scope.vysledok1 = ...; $(el).eq(0).show(); $scope.vysledok2 = ...; $(el).eq(1).s… nový
Mlocik97 02.10.2018 21:57
Mlocik97

problém vidím asi v tomto:

[qamRKkx.png]

tretí a paty riadok v screenshote sú súbory s dátami ktoré sa používajú pre výpočet výsledku ktorý sa binduje. P.S. asi som mal zmíniť že dáta ktoré priraďujem do $scopu a následne sa bindujú že sú vnorené vo funkcii ktorá sa volá po dokončení predchádzajúcej funkcii (AJAX requestu)... asi tým že používam .then() to asi taky neco delá, lenže inak než s tým .then() to nemá ako spraviť.

Co teda to obejít takto? Při spuštění aplikace (načtení webu) se zobrazí jen prázdná stránka (nebo stránka s obyč. textem, něco ve smyslu placeholder) a přes časovací funkci setTimeout() se nastaví zavolání požadované stránky, tj. změní se programově adresa v $routeProvider třeba za 100ms?

skusil som to ešte trocha iným spôsobom, ktorý funguje tak trocha opačne, pri bežnom načitávaní to funguje super, pri pomalom načitávaní rádovo pri rýchlostiach slow 3G tak vidno prebliknutie teraz tak že sa dáta nabindujú ešte skorej než sa zobrazí ten text ktorý už v HTML bol, čož je opak toho čo som teraz riešil. Spôsobilo to to že za funkcí kde jsem vykonával výpočet výsledku pre binding tak som použil .then(function() {$scope.loaded = true}; a pak som všade do if direktív napcal loaded hodnotu. Neviem jak to ale spraviť tak aby sa to presne postupne načítalo. Resp prvý binding, zobrazenie textu za ním, druhý binding za prvým textom, zobrazenie textu za druhým bindingom. atd.

Predstav si takú situáciu že pôvodne sa mi to načitávalo takto (hviezdička predstavuje začiatok riadku):

prvá snímka:


*
*neco
*
*

druhá snímka:


*bindované dáta
*ďalšie bindované dáta
*neco
*

tretia snímka:


*bindované dáta
*ďalšie bindované dáta
*neco
*a ďalšie bindované dáta

jak vidíš text "neco" bylo skorej na druhom riadku, potom na tretom, pretože bindované dáta to odsunuli, keďže to neco v prvej snímke na druhom riadku bolo vykreslené len asi 60ms, tak to vyzeralo ako prebliknutie.
po mojom pokuse o riešení:

prvá snímka:


*bindované dáta
*ďalšie bindované dáta
*
*

druhá snímka:


*bindované dáta
*ďalšie bindované dáta
*a ďalšie bindované dáta
*

tretia snímka:


*bindované dáta
*ďalšie bindované dáta
*neco
*a ďalšie bindované dáta

Jo, už chápu. Zkus teda prvně zobrazit prázdnou stránku a po načtení dat z AJAX volání přes routerProvider změnit url a tím načíst tvou stránku - pokud teda ten AJAX neprobíhá v controlleru.

Ještě mě napadlo: nemá Angular něco jako resolve? Ve smyslu "dokud nemám data, nedojde k zobrazení stránky"?

pozerám toto by mohlo byť asi najlepšie riešenie.

tak to nechápem, ale i s týmto kódom:


resolve: {
			app: function($q) {
				var defer = $q.defer();
				defer.resolve();
				return defer.promise;
			}
		}

to preblikáva... asi sa s tým ešte musím pohrať, zrejme chybu niekde robím ja.

<span ng-if="loaded && step > 0">Tohle jako první</span><span ng-if="loaded && step > 1">Tohle jako druhé</span>

V tom volání AJAXu si vždy ve funkci co je uvnitř .then() nastavíš hodnotu proměnné step. Provede se první volání AJAX a vrátí se výsledek, nastavím step = 1; provede se druhý volání AJAX a vrátí se výsledek, nastavím step = 2.

A je to :-)

Dík, skúsil som to a funguje to. Akurát mi to prijde trocha nepraktické. To už pak neni lepšie volať rovno funkci show() na oindexované elementy, teda že bych tým elementom nastavil class="i/* číslo */"? Myslím že tá premenná counter pak zbytočne bere výkon i zaberá RAM protože mám o premennú navyše. Nakoniec to vyzerá že zostanem pri starom riešení. Resp. ani nemusím nastavovať tie classy. Využijem pseudo selector nth-type-of.

Tak som to nakoniec vyriešil ešte úplne inak, riešením ktoré sa mi docela páči.

Postupnosť načitávania som zaistil tým že som namiesto toho kde bych psal "counter++" tak som využil funkcie eq(), funguje to dokonale.

.then(function() {
    $scope.vysledok1 = ...;
    $(el).eq(0).show();
    $scope.vysledok2 = ...;
    $(el).eq(1).show();
    ...
})

Je to riešenie docela blízko mojmu pôvodnému (to riešenie som však nechcel kvôli tomu že boli elementy rôzne zanestované, avšak funkce eq() nepočíta poradie el v určitom elemente jako nth-neco selectory a pod. takže viem "počítať poradie" aj skrz rôznak zanestované elementy. Ostatne stále je to riešenie možno nie najlepšie.

Zpět do poradny Odpovědět na původní otázku Nahoru