Wojciech Mazurek

Wojciech Mazurek właściciel, PPHU
Neuron

Temat: callback i wywoływanie z zewnątrz prywatnych funkcji

To znowu ja ;)

Dwa pytania.

Mam jakiś kod biblioteczny. W nim w jakiejś funkcji wołam funkcję z głównej części kodu
np

// biblioteka
jakas_funkcja_np_ajax()
{
coś_tam
DataOK();
}
// kod główny
function DataOK(){
tu coś robimy
}

I jest fajnie. Ale chciałbym aby kod dział prawidłowo kiedy nie ma w głównym kodzie funkcji DataOK.
Czy JS ma coś takiego jak typ proceduralny abym mógł funkcję DataOK zadeklarować jako zmienną i przypisać jak będzie potrzebna a jak nie to domyślnie przypisać coś pustego ?

Drugi mój problem jest jeszcze bardziej zagmatwany

Mam funkcje (taki przykład):

MakeButton: function (bt) {
var CurrentButton=$(bt);
var bcount =0;
var timer = $.timer(
function() {
bcount++;
$(CurrentButton).html(bcount);
},
1000,
true
);
$(CurrentButton).click( function() {
bcount=0;
}
)}


Dodaje do wskazanego buttona timer który nabija i wyświetla na nim licznik i zdarzenie które ten licznik kasuje.

Ale ja bym chciał zrobić to inaczej.
Chciałbym aby wewnątrz funkcji MakeButton była funkcja
doTimer(){
bcount++;
$(CurrentButton).html(bcount);
}

Chciałbym mieć jeden globalny timer i listę na której funkcja
zarejestruje buttona ( albo dowolny inny element obrabiany np przez funkcje MakeImage etc )
i żeby to ten centralny timer wołał funkcję doTimer wszystkich zarejestrowanych elementów.
Ewentualnie zamiast listy może jakieś znakowanie elementu np jakąś klasą css tak aby centralny timer mógł zrobić literacje po DOMie, np. coś w stylu $.( jakis_warunek ).doTimer;

No i nie mam pomysłu (wiedzy) jak to zrobić ;)


konto usunięte

Temat: callback i wywoływanie z zewnątrz prywatnych funkcji

Wojciechu, może czas usiąść i nauczyć się JavaScript ? Bo właściwie na początku zapytałeś o funkcje anonimowe gdzie sam takową widzę zastosowałeś w kodzie który pokazałeś. Znowu globalny timer to nie problem z uwagi na to domknięcia JavaScript więc możesz sobie ustawić jakiś obiekt do którego rejestrujesz timery i operować na nim skąd chcesz.

Normalnie bym Ci po prostu odpowiedział i dał gotowca ale jak pytasz o funkcje anonimowe jednocześnie je używając no to wiesz :PDariusz Półtorak edytował(a) ten post dnia 22.06.12 o godzinie 08:19
Piotr Koszuliński

Piotr Koszuliński JavaScript ninja

Temat: callback i wywoływanie z zewnątrz prywatnych funkcji

Dariusz Półtorak:
Wojciechu, może czas usiąść i nauczyć się JavaScript ?

Popieram. Zadajesz dużo pytań, liczysz na to, że ktoś poświęci czas na opisanie Ci tego, a później i tak nic z tego nie ma, bo nawet nie rozumiesz w pełni naszych odpowiedzi. Brakuje Ci podstaw i bez tego będziesz musiał pytać o wszystko. Zmarnujesz swój i nasz czas :)

Dlatego polecam przysiąść do jakiejś dobrej książki o JS. Standardowo polecamy wtedy JavaScript The Good Parts Crockforda.
Wojciech Mazurek

Wojciech Mazurek właściciel, PPHU
Neuron

Temat: callback i wywoływanie z zewnątrz prywatnych funkcji

Macie Panowie obaj rację.
Śmiem przypuszczać że obaj programujecie w wielu językach - choćby JS i PHP, ale też przypuszczam że wiedzę na temat tych języków zdobywaliście równolegle.

Uwierzcie mi proszę - nauczyć się języka to pestka - oduczyć się języka którego używa się od 20 lat
to jest dopiero problem....

Nie oczekuje gotowych rozwiązań które sobie wkleję. Raczej gotowych kawałków kodu które chmm jak by to powiedzieć - będą inspiracją. Czasami można czytać i czytać i nie kumać I wystarczy jeden dobry przykład, albo jedno zdanie i wszystko staje się jasne.
Nawiasem mówiąc - wiecie jak ciężko się przyzwyczaić do takich "dziwactw" jak to ze procedura
która jest wewnątrz tekstu (z naciskiem na słowo tekst) innej procedury działa asynchronicznie skoro człowiek zawsze musiał robić oddzielne wątki i je synchronizować aby uzyskać działanie asynchroniczne?
Czasami zapominam ze JS jest skryptem dla innego programu który sobie może z nim zrobić cokolwiek ( tym jest to dziwniejsze że sam napisałem dwa interpretery i korzystam w moim sofcie z dość silnego, obcego silnika interpretera) a nie typowym, tłumaczonym na kod maszynowy językiem.
Zresztą do ObjectPaskala przeszedłem ze zwykłego Paskala i asemblera i też się przez wiele miesięcy nie mogłem nadziwić nad moją głupota ;)))

A co do książek - chmm - większość opisuje jak się język używa a nie jak on jest zbudowany, o tym co jest pod maską to zapomnij. Mam 3 książki, w każdej piszą o timerach, w żadnej o tym że timery w JS działają na jednym wątku co akurat dla mnie jest sprawą kluczową.

Tak więc Panowie - trochę cierpliwości i wyrozumiałości please ;)))))

konto usunięte

Temat: callback i wywoływanie z zewnątrz prywatnych funkcji

Wybacz ale programowałem w C++ na samym początku. Nie przeszkadzało mi to w zejściu troszkę niżej do Assemblera w którym właściwie możemy zrobić to samo tylko trzeba się więcej spisać no i jednak wszystko robi się zupełnie inaczej. To samo z MoscowML (implementacja SML) w którym programowanie funkcyjne i wszechobecna rekurencja są na porządku dziennym. Międzyczasie był Pascal, Delphi i Java.
Później doszło PHP które wymagało ponownej zmiany w myśleniu bo nie pracowałem z aplikacją która działa ciągle tylko per request.

JavaScript w ogóle jest odmiennym językiem z uwagi na to że mamy do czynienia z obiektowym językiem bazującym na prototypach gdzie domknięcia i funkcje anonimowe pełnią ogromną rolę.

Ale wszystkich tych rzeczy trzeba się było po prostu nauczyć. Usiąść, wziąć literaturę (preferuję) lub kurs online i się nauczyć. Oba pytania które zadałeś to po prostu PODSTAWA jeżeli chodzi o JavaScript.

Funkcje anonimowe, spójrz na to co sam podałeś:

MakeButton: function (bt) {
var CurrentButton=$(bt);
var bcount =0;
var timer = $.timer(
function() {
bcount++;
$(CurrentButton).html(bcount);
},
1000,
true
);
$(CurrentButton).click( function() {
bcount=0;
}
)}


Czy zdajesz sobie sprawę że w tym momencie przypisałeś funkcję anonimową do "MakeButton" ? Więc od teraz możesz używać jakiś tam obiekt.makeButton(param); ?? Więc czemu nie miał byś tego samego zrobić od innej zmiennej ?


var test = function() {
alert('test');
}

test();


?? Domknięcia sprawiają że wnętrze funkcji używa wszystkich zmiennych które są widoczne w wyższym zasięgu i nie trzeba żadnego dodatkowego zapisu by to osiągnąć. Więc zobacz sobie to:

var a = 1;
var b = 1;

function test() {
var a = 5;
console.log('test');
console.log(a);
console.log(b);
a = 6;
b = 6;
console.log(a);
console.log(b);
}

console.log('start');
console.log(a);
console.log(b);
test();
console.log('po test');
console.log(a);
console.log(b);


I zobacz wyniki w konsoli. Wybacz ale Tobie się po prostu nie chce i szukasz wymówki. Nikt Ci nie każe "ODUCZYĆ" się jakiegokolwiek języka w którym piszesz 20 lat. My tylko sugerujemy byś się "NAUCZYŁ" języka którym chcesz się posługiwać.

Tekst który słyszałem podczas prezentacji Google na temat JavaScript nadal aktualny. Z jakiegoś powodu niektórzy programiści są święcie przekonani że JavaScript to jedyny język który mogą używać nie poznając go.
Wojciech Mazurek

Wojciech Mazurek właściciel, PPHU
Neuron

Temat: callback i wywoływanie z zewnątrz prywatnych funkcji

Dariusz Półtorak:
Tekst który słyszałem podczas prezentacji Google na temat JavaScript nadal aktualny. Z jakiegoś powodu niektórzy programiści są święcie przekonani że JavaScript to jedyny język który mogą używać nie poznając go.

Dobre, dobre ;)))

Przede wszystkim dziękuję za odzew - nie mam z kim podyskutować dlatego miedzy innymi piszę tutaj na grupę, nie po to aby ktoś mi przygotowywał gotowce.
Problem jest taki że mówimy o tym samym ale nie tymi samymi słowami. Mówiąc że ciężko się
oduczyć jakiegoś języka miałem na myśli między innymi terminologię.

Dlatego też pełen pokory muszę zadać pytanie czy aby na pewno kolega dobrze przeczytał moje pytanie - oczywiście biorąc poprawkę na ww terminologię właśnie.

Napisałeś: "Więc od teraz możesz używać jakiś tam obiekt.makeButton(param)"
Otóż nie. MakeButton nie jest nową metodą obiektu - jest procedurą narzędziową która
dodaje do obiektu obsługę click() i timera ale nie można jej wywołać (może można mnie już niewiele dziwi) jako metodę zmodyfikowanych przez nią obiektów.

A więc jeszcze raz - zmodyfikowałem trochę przykład:

MakeButton: function (bt) {

// coś co ja nazywam metodą prywatną
function foo(){ $(bt).html('na dziś koniec') }

var CurrentButton=$(bt);
var bcount =0;
var timer = $.timer(
function() {
bcount++;
$(CurrentButton).html(bcount);
if (bcount > 10) {foo();};
},
1000,
true
);
$(CurrentButton).click( function() {
bcount=0;
}
)}


jeśli w kodzie zrobię coś takiego :

// modyfikacja butonnów
$.myF.MakeButton('#b1');
$.myF.MakeButton('#b2');
$(#b2').foo;


To oczywiście trzeci wiersz zostanie zakwestiowany przez interpreter co jest oczywiste bo metoda foo jest metodą prywatną obiektu ( domkniętą, zamkniętą, zaaresztowaną, zwał jak zwał - chodzi o logikę programowania obiektowego)

I teraz chodzi mi o dwie rzeczy
- jak zadeklarować metodę foo i DODAC ją do obiektu (bo teraz jest metodą prywatną funkcji narzędziowej a nie obiektu choć działa na każdej kopii obiektu co też mnie trochę dziwi jakim cudem ) aby była publiczna aby wywołanie $(#b2').foo; było prawidłowe

- jak zrobić literację po obiektach np

$( wszystkie_obiekty_którym_dopieto_metode_foo ).foo;

zakładając że metodę foo mogą mieć różne obiekty w drzewie DOM, bo metodę foo doda też
makeImage, makeGauge makeTrend itd....Wojciech Mazurek edytował(a) ten post dnia 22.06.12 o godzinie 15:11

konto usunięte

Temat: callback i wywoływanie z zewnątrz prywatnych funkcji

Wojtku, nie patrz na JS przez perspektywę klasycznego OOP.
Nie pisz w stylu a'la jQuery - wg mnie to jest jeden wielki chaos i rypanie się z kontekstami (i w ogóle olej jQuery - są leprze rzeczy do tego).

Proponuję byś pisał w następujący sposób:

var Button = function(DOMNode){
this.node = DOMNode;
}
Button.prototype.foo = function(arg1, arg2) { ... }
Button.prototype.bar = function(arg1, arg2) { ... }


A potem wywołanie tego:

var Node = document.getElementById('#button1');

var CurrentButton = new Button(Node);
var result = CurrentButton.foo(1, 2);


A jak chcesz w w tablicy to:

var ButtonCollection = [];
ButtonCollection.push( new Button( document.getElementById('#button1') ) );
ButtonCollection.push( new Button( document.getElementById('#button2') ) );
ButtonCollection.push( new Button( document.getElementById('#button3') ) );
ButtonCollection.push( new Button( document.getElementById('#button4') ) );


Jeżeli nie potrzebujesz rzeczywistego licznika czasu a jedynie reakcję na jakieś kliknięcie, najechanie kursorem czy też reakcję na zdarzenie wewnątrz własnych obiektów/funkcji - możesz sam wywoływać zdarzenia i do nich podpinać obsługę.

Dodatkowo - proponuję odseparować obsługę zdarzenia od implementacji - chodzi mi o to byś w reakcji na zdarzenie nie wywoływał jakiejś anonimowej funkcji a metodę obiektu (oczywiście jeśli ma to sens).
Nie dość że łatwiej będzie się w kodzie połapać, to jeszcze w reakcji na inne zdarzenia będziesz mógł używać tej samej metody.
Wojciech Mazurek

Wojciech Mazurek właściciel, PPHU
Neuron

Temat: callback i wywoływanie z zewnątrz prywatnych funkcji

Michał Wachowski:
Wojtku, nie patrz na JS przez perspektywę klasycznego OOP.
Nie pisz w stylu a'la jQuery - wg mnie to jest jeden wielki chaos i rypanie się z kontekstami (i w ogóle olej jQuery - są leprze rzeczy do tego).
W kontekście tego co konkretnie chcę zrobić w pierwszej kolejności to jQuery ma dużo zalet - choćby kolekcję dodatków ale też możliwości tworzenia prostego, nazwijmy go frontowego kodu.

W mojej aplikacji to user sam ma sobie zrobić interfejs aplikacji (nie stronę www) używając do tego
jak najprostszych przygotowanych narzędzi. Jak zwykle prosto dla usera zero oznacza horror dla programisty ;)

Koncepcja jest mniej więcej taka:
robię sobie (user końcowy) kod (składnia moze być niedbałą - chodzi o idee)



<body>
<img src='plan_posesji.png ID="plan">

<img src="" ID="Brama">
<img src="" ID="Lampa">
</body>
<script>

function Hall_init();
{
MakeImage(
iDimage:"#Brama",
idParent: "#Plan",
x:120,
y:211,
iOn: "Brama_on.png",
iOff: "Brama_off.pg",
Vbit: 31
)
// na współrzędnych obrazka plan umieść obrazek brama i ładuj odpowiednią
// grafikę w zależności od stanu zmiennej Vbit

MakeImageAsButton(
iDimage:"#Lampa",
idParent: "#Plan",
x:120,
y:211,
iOn: "lampa_on.png",
iOff: "lampa_off.pg",
iHoverOn: "lampa_on_h.png",
iHoverOff: "lampa_off_h.png",
Vbit: 31
Action: Task11
)
// na współrzędnych obrazka plan umieść obrazek lampa i ładuj odpowiednią
// grafikę w zależności od stanu zmiennej Vbit,
// zamień ja w przycisk, po przyciśnięciu wywołaj akcję "task" serwera

}
</script>

Tyle i TYLKO TYLE ma zrobić user - cała reszta ma być dla niego przezroczysta - no chyba
że to któryś z szanownych kolegów będzie chciał sobie trochę podautomatyzować domostwo to wtedy będzie mógł sam sobie obsłużyć komunikację JSON wedle własnego uznania.

No i na razie uczę się tego wszystkiego i kombinuję jak koń pod nie jak coś zrobić tylko jak zrobić aby komuś było jak najłatwiej.

konto usunięte

Temat: callback i wywoływanie z zewnątrz prywatnych funkcji

Dlatego właśnie Ci mówimy żebyś najpierw nauczył się JavaScript zanim zaczniesz go używać :P

konto usunięte

Temat: callback i wywoływanie z zewnątrz prywatnych funkcji

tylko, że w jQuery da się to wszystko krócej zapisać:
var buttonCollection = ['#button1', '#button2', '#button3'];
var count = 0;
buttonCollection.push("#kolejny-button");

setInterval(function(){
$.each(buttonCollection, function() {
$(this).html(count++);
});
}, 1000);


$.each - iteruje po wszystkich obiektach w kolekcji, odsyłam do dokumentacji.

function Hall_init(); // <--- wywal
{
MakeImage(
iDimage:"#Brama",
idParent: "#Plan",

Wywal średnik po nagłówku funkcji. Poza tym wstawiaj na końcu każdej normalnej linijki (Google: semicolon javascript, semicolon insertion)Łukasz Lityński edytował(a) ten post dnia 22.06.12 o godzinie 17:14



Wyślij zaproszenie do