MVC -podstawowe pytania

MVC -podstawowe pytania
KA
KA
  • Rejestracja:prawie 12 lat
  • Ostatnio:prawie 5 lat
  • Lokalizacja:Warszawa
  • Postów:1683
0

Hej przeczytałam kilka tutoriali i mam kilka pytań odnośnie MVC

  1. W modelu siedzi klasa Student i StudentsBase, operuję głównie na StudentsBase , naciskam sobie w widoku "Sort Students" - sortowaniem powinien zająć się kontroler i odpowiednio uaktualnić model czy model powinien udostępniać prostą metodę do sortowania (dla kontrolera) np. students.Sort()? Bo np. gdy naciskam w widoku "Show Smokers" i chcę tylko wyświetlić sobie palących studentów (dane w bazie nie ulegną zmianie) to domyślam się, że to już zadanie dla kontrolera, który pobiera sobie dane z modelu i je odpowiednio przetwarza tak? (a potem to co przetworzył przekazuje do widoku)

  2. Obecnie w main mam coś takiego:

Kopiuj
Model model = new Model();
View view = new View(model);
Controller controller = new Controller(model,view);

przez to mam tylko jedną klasę w kontrolerze do "komunikacji" z modelem o nazwie Model. Będę musiała nawrzucać tam sporo metod - tak się robi czy można stworzyć sobie więcej klas i je przekazywać do kontrolera np. Controller controller = new Controller(groupsModel,studentsModel,view); itd... ?

  1. jest klasa StudentsDatabase- jak powinno wyglądać z perspektywy kontrolera dodanie nowego studenta do bazy studentów tj. modelu?
    students.add(String name, int age, boolean isDrunk); (wtedy tych parametrów może być dużo)
    czy
Kopiuj
Student s = new Student(String name, int age);
s.learning(String learningWhat);
s.sleeping();
students.add(s);

tylko wtedy będę musiała zrobić klasę Student w modelu publiczną i dodać w kontrolerze import model.Student;

--no właśnie tutaj mam kolejne pytanie:
4. Obecnie w pakiecie model na klasę Model (która jest jedyną z tego pakietu używaną zewnętrznie) składa mi się kilka mniejszych klas. Żeby je ukryć nie daję żadnego modyfikatora tj;
"default – pozwala na dostęp do danego elementu tylko klasom z danego pakietu (nie istnieje słowo w Javie określające ten rodzaj dostępu, jeżeli chcemy go użyć to po prostu nie podajemy żadnego modyfikatora)"

czy to jest słuszna praktyka?

PS jeżeli znacie jakieś ciekawe materiały o MVC z przykładami w Javie (jak to się prawidłowo robi) to proszę o link :p .
znalazłam coś takiego: http://www.know-how.info.pl/programowanie/java/wzorce-projektowe/klasyczny-mvc/
Pozdrawiam


PROGRAMY NA ZAMÓWIENIE, ZALICZENIA STUDENCKIE, KONFIGURACJA SERWERÓW, SYSTEMÓW I BAZ DANYCH, STRONY INTERNETOWE, POMOC W PROGRAMOWANIU, POPRAWIENIE I OPTYMALIZACJA APLIKACJI
JAVA, C++, LINUX, WWW, SQL, PYTHON
POSIADAM KOMERCYJNE DOŚWIADCZENIE
TANIO, SZYBKO I PORZĄDNIE
Z KOMENTARZAMI OBJAŚNIAJĄCYMI KOD
PISZ NA PRYWATNĄ WIADOMOŚĆ
CENY JUŻ OD 49,99ZŁ ZA PROGRAM
ZAJMIJ SIĘ TYM CO CIĘ NAPRAWDĘ INTERESUJE!
Koziołek
ad 4. jest słowo kluczowe default i jest ono nieobowiązkowe.
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
1
  1. Ale to sortowanie chcesz przeprowadzić faktycznie na modelu (tzn to jest "posortuj mi wszystkich studentów w bazie!") czy chcesz to sobie posortować w widoku po prostu? Jeśli to drugie to ja bym powiedział że to jest zadanie widoku na dobrą sprawę ;]
    Jeśli chodzi o smokerów to nie do końca. Bo rzadko kiedy mamy coś takiego jak faktycznie tylko 3 elementy -> model, widok, kontroler. W praktyce pomiędzy danymi w bazie a kontrolerami jest wiele poziomów logiki biznesowej, więc można powiedzieć że "model" jest mocno rozbudowany. W realnym systemie, w trywialnym przypadku, byłaby warstwa dostępu do danych a nad nią byłaby warstwa "serwisów" z której korzystałyby kontrolery. Kontroler poprosiłby odpowiedni serwis o dane palaczy a potem zwrócił by te dane do widoku.

  2. Raczej robi się tych klas wiele. Bardzo wiele. Dlatego normalni ludzie używają kontenerów IoC a nie tworzą obiekty przez new ;) Bo Kontrolerów też może być więcej niż jeden (podpięte w różnych miejscach) i widoków oczywiście też. Bo jak masz aplikację większą niż hello world to przecież taki obiekt "Kontroler" to by był jakis God-Object (patrz: antywzorzec projektowy).

  3. Ani jedno ani drugie tak naprawdę. Powinna być osobna klasa (!) na dane studenta która jest wypełniana danymi wprowadzonymi przez uzytkownika. Od biedy można użyć samej klasy Student, ale jak korzystasz później z ORMów to powoduje to czasem pewne kłopoty jak ktoś nie do końca rozumie jak działają transakcje i sesje. W twoim przypadku ta druga opcja jest sensowniejsza.

  4. Istnieje słowo i brzmi ono "package private" / dostęp pakietowy. Nie rozumiem pytania. Pytasz czy słuszne jest ukrywanie klas których nikt nie powinien widzieć? Tak ;]


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
DZ
  • Rejestracja:około 14 lat
  • Ostatnio:około 8 lat
  • Postów:76
1

@karolinaa

  1. Nie dokładnie tak
    Kontroler pełni pewną warstwę abstrakcji pomiędzy klientem a aplikacją (dla kontrolera nie jest istotne czy user klika w aplikacji czy żądania przychodzą z http). Kontroler ma za zadanie po prostu delegować żądania. W Twoim przypadku: klikasz sort na widoku -> na kontrolerze wywołujesz sort, np.
Kopiuj
public void sort() {
    model.sort();
}

a całą logikę biznesową realizuje model i jego serwisy. Jak już serwis posortuje odpowiednio dane czy też za pomocą odpowiedniego sql'a wyciągniesz je z bazy to tylko uaktualniasz (ustawiasz modelowi kolekcję z odpowiednimi danymi) a obserwator update'uje widok. Widać tutaj że kontroler uczestniczy tylko w przekazaniu żądania - nigdzie więcej. Implementując bardzo prosty wzorzec Obserwator (w standardowym API lub swój) sprawisz, że widok uaktualni się "automatycznie" gdy tylko zmieni się stan danych.

Ale jeżeli nie masz zamiaru zmieniać danych w bazie ani w modelu to jak kolega wyżej napisał to zadanie widoku.

  1. W tym przypadku konstruktory MVC wyglądają ok.
    Ja jednak tworzę odpowiedni widok w kontrolerze, tam też dla np. aplikacji z GUI wiąże listenery, dzięki czemu odpowiednio deleguje żądania z np. kliknięcia na jakiś button do modelu.
    Jak koledzy wyżej napisali: wiele klas i pamiętaj że aplikacja może korzystać z wielu modeli, widoków i kontrolerów.

  2. Danych dla studenta prawdopodobnie tyle ile zdefiniujesz na widoku.
    Mogło by to wyglądać np tak, że w kontrolerze masz metodę:

Kopiuj
public addStudent(param1, param2, ...) {
    model.addStudent(param1, param2, ...);
}

Gdyby tych parametrów było bardzo dużo możesz np. użyć wzorca Builder. Kontroler nie powinien wiedzieć że istnieje coś takiego jak Student - ba, nawet go to nie obchodzi.

  1. To jest słuszna praktyka jeżeli chcesz mieć "zasięg pakietowy".
edytowany 5x, ostatnio: dzanesko
n0name_l
Ale wiesz, ze sortowanie danych w widoku to nijak ma sie do logiki biznesowej? ;)
DZ
Ale ani ja ani nikt powyżej nie próbuje sortować danych w widoku :) Sortowanie należy zdelegować do modelu który wg głównego założenia MVC realizuje logikę biznesową aplikacji.
n0name_l
Ale to sie wlasnie robi w widoku! Logika biznesowa modeluje procesy biznesowe, a nie to jak user sobie bedzie przegladac tabelki. Nazywanie sortowania danych dla usera logika biznesowa jest jakims wielkim nieporozumieniem.
DZ
Ok, z mojego opisu wynika że pomyliłem sortowanie z filtrowaniem - dlatego pisałem m.in. o wyciąganiu danych z bazy. Jeżeli chodzi o samo sortowanie to dokładnie tak jak piszesz robi się to na "guicu"
KA
KA
  • Rejestracja:prawie 12 lat
  • Ostatnio:prawie 5 lat
  • Lokalizacja:Warszawa
  • Postów:1683
0

Tak chodziło mi o sortowanie bez wpływu na model, no ale okey czyli już wiem, że to zadanie dla widoku. Co do zasięgu też już wiem. Mam teraz inny kłopot - czy sprawdzać poprawność wprowadzonych danych w widoku ma widok i tylko widok? np. mam w widoku metodę zwracającą wprowadzone ID:

Kopiuj
public int getStudentId() {
	return new Integer(txtId.getText());
}

a użytkownik nie poda ID albo poda ID, które nie istnieje w bazie i kliknie na btnDelStudent. I teraz nie umiem tego zrobić. Mam dwa ActionListenery dla tego przycisku jeden w kontrolerze i jeden w widoku. zmieniłam w widoku metodę zwracającą wprowadzone id:

Kopiuj
public int getStudentAge() {
	try {
		return new Integer(txtAge.getText());
	} catch (NumberFormatException e) {
		return -1;
	}
}

i po prostu za każdym razem w kontrolerze sprawdzam id zwrócone z widoku:

Kopiuj
/* ActionListener w kontrolerze dla klikniecia w btnDelStudent */
class delStudentListener implements ActionListener {
	public void actionPerformed(ActionEvent e) {
		int id = view.getStudentId();
		if (id < 0 || id > model.getNofStudents()) {
			view.addToConsole("ERROR: podales zle ID");
			return;
		}
		Student s = model.getStudent(id);
		view.addToConsole("WYKASUJE " + s);
		model.delStudent(id);
	}
}

Ale czy to tak się powinno robić?
I ostatnie pytanie - widzę tutaj http://www.know-how.info.pl/programowanie/java/wzorce-projektowe/klasyczny-mvc/ ,że widok zmienił coś w modelu bez udziału kontrolera.
Czy jest dobra praktyka?

@Shalom
Dobra kontenery IoC, serwisy itd... ale wiesz ja póki co jestem początkująca.


PROGRAMY NA ZAMÓWIENIE, ZALICZENIA STUDENCKIE, KONFIGURACJA SERWERÓW, SYSTEMÓW I BAZ DANYCH, STRONY INTERNETOWE, POMOC W PROGRAMOWANIU, POPRAWIENIE I OPTYMALIZACJA APLIKACJI
JAVA, C++, LINUX, WWW, SQL, PYTHON
POSIADAM KOMERCYJNE DOŚWIADCZENIE
TANIO, SZYBKO I PORZĄDNIE
Z KOMENTARZAMI OBJAŚNIAJĄCYMI KOD
PISZ NA PRYWATNĄ WIADOMOŚĆ
CENY JUŻ OD 49,99ZŁ ZA PROGRAM
ZAJMIJ SIĘ TYM CO CIĘ NAPRAWDĘ INTERESUJE!
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
1

A bym rzucił wyjątkiem zamiast zwracać jakąś arbitralną wartość określającą kod błędu ;)

Dobra kontenery IoC, serwisy itd... ale wiesz ja póki co jestem początkująca.

Tym bardziej powinnaś uczyć się dobrych praktyk ;)


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
DZ
  • Rejestracja:około 14 lat
  • Ostatnio:około 8 lat
  • Postów:76
1

Modyfikowanie modelu przez widok jest niedopuszczalne! Widok - jak nazwa wskazuje ma wyświetlać to co "oferuje" model.

Co do kodu:

Kopiuj
public int getStudentAge() {
    try {
        return new Integer(txtAge.getText());
    } catch (NumberFormatException e) {
        return -1;
    }
}

Raczej nie należy programować defensywnie. Ogólne założenie metody jest OK: get czyli zwróć poprawną wartość albo Exception. Ale try/catch wygląda tutaj tak jakbyś spodziewała się błędu. Jak wyżej: lepiej rzucić Exception lub oddelegować go dalej:

Kopiuj
public int getStudentAge() throws NumberFormatException {
    return Integer.parseInt(txtAge.getText());
}

niż zwracać -1.

edytowany 1x, ostatnio: dzanesko
KA
KA
  • Rejestracja:prawie 12 lat
  • Ostatnio:prawie 5 lat
  • Lokalizacja:Warszawa
  • Postów:1683
0
dzanesko napisał(a):

Modyfikowanie modelu przez widok jest niedopuszczalne! Widok - jak nazwa wskazuje ma wyświetlać to co "oferuje" model.

Okey czyli ten model, który przekazuje do widoku View view = new View(model); mogę go rozumiem używać tylko "read-only" ? (metody typu np. `model.get*)


PROGRAMY NA ZAMÓWIENIE, ZALICZENIA STUDENCKIE, KONFIGURACJA SERWERÓW, SYSTEMÓW I BAZ DANYCH, STRONY INTERNETOWE, POMOC W PROGRAMOWANIU, POPRAWIENIE I OPTYMALIZACJA APLIKACJI
JAVA, C++, LINUX, WWW, SQL, PYTHON
POSIADAM KOMERCYJNE DOŚWIADCZENIE
TANIO, SZYBKO I PORZĄDNIE
Z KOMENTARZAMI OBJAŚNIAJĄCYMI KOD
PISZ NA PRYWATNĄ WIADOMOŚĆ
CENY JUŻ OD 49,99ZŁ ZA PROGRAM
ZAJMIJ SIĘ TYM CO CIĘ NAPRAWDĘ INTERESUJE!
DZ
  • Rejestracja:około 14 lat
  • Ostatnio:około 8 lat
  • Postów:76
1

Tak, tylko i wyłącznie w trybie read-only.

KA
KA
  • Rejestracja:prawie 12 lat
  • Ostatnio:prawie 5 lat
  • Lokalizacja:Warszawa
  • Postów:1683
0

finalnie zrobiłam to tak w kontrolerze:

Kopiuj
class delStudentListener implements ActionListener {
	public void actionPerformed(ActionEvent e) {
		try {
			int id = view.getStudentId();
			Student s = model.getStudent(id);
			model.delStudent(id);
			view.addToConsole("Usuwam " + s);
		} catch(NumberFormatException ee) {
			view.addToConsole("ERROR: ID tylko cyfry");
		} catch(IndexOutOfBoundsException aa) {
			view.addToConsole("ERROR: Nie ma takiego ID");
		}
	}
}

view.getStudentID() rzuca wyjątkiem a model.getStudent(id); rzuca tym drugim (IndexOutOfBoundsException).
model.delStudent(); ani view.addToConsole() nie rzuca żadnym, ale jeszcze o tym pomyślę w przyszłości (muszę doczytać o tych wyjątkach).
Dzięki za pomoc


PROGRAMY NA ZAMÓWIENIE, ZALICZENIA STUDENCKIE, KONFIGURACJA SERWERÓW, SYSTEMÓW I BAZ DANYCH, STRONY INTERNETOWE, POMOC W PROGRAMOWANIU, POPRAWIENIE I OPTYMALIZACJA APLIKACJI
JAVA, C++, LINUX, WWW, SQL, PYTHON
POSIADAM KOMERCYJNE DOŚWIADCZENIE
TANIO, SZYBKO I PORZĄDNIE
Z KOMENTARZAMI OBJAŚNIAJĄCYMI KOD
PISZ NA PRYWATNĄ WIADOMOŚĆ
CENY JUŻ OD 49,99ZŁ ZA PROGRAM
ZAJMIJ SIĘ TYM CO CIĘ NAPRAWDĘ INTERESUJE!
edytowany 1x, ostatnio: karolinaa
DZ
  • Rejestracja:około 14 lat
  • Ostatnio:około 8 lat
  • Postów:76
0

Nie wiem dokładnie jak wygląda cała implementacja ale:

  1. pobierasz id z gui
  2. tworzysz studenta pobierając go z modelu
  3. następnie usuwasz tego studenta
  4. i na koniec wyświetlasz już nie istniejącego studenta

Zamiast klasy delStudentListener w kontrolerze zrobiłbym metodę:

Kopiuj
public void deleteStudent(int id) {
    model.deleteStudent(id);
}

w modelu:

Kopiuj
public void deleteStudent(id) {
    // usuwanie studenta
    // update widoku
}

Kontroler powinien zdelegować akcję do modelu a ten powinien zająć się logiką.
Exception typu "litera zamiast cyfry" możesz walidować na widoku wyśweitlając np. komunikat aż do momentu wprowadzenia cyfry. Model, który dostanie już poprawną wartość w zależności od tego czy student istnieje czy też nie uaktualni odpowiednio widok.

edytowany 2x, ostatnio: dzanesko
KA
KA
  • Rejestracja:prawie 12 lat
  • Ostatnio:prawie 5 lat
  • Lokalizacja:Warszawa
  • Postów:1683
0

@dzanesko racja poprawiłam.

dzanesko napisał(a):

w modelu:

Kopiuj
public void deleteStudent(id) {
    // usuwanie studenta
    // update widoku
}

Kontroler powinien zdelegować akcję do modelu a ten powinien zająć się logiką.

to model może sterować widokiem? czyli tak teoretycznie:

  • Widok: może korzystać ro model
  • Kontroler: może korzystać rw z modelu i odświeżać widok
  • Model: może odświeżać widok?

PROGRAMY NA ZAMÓWIENIE, ZALICZENIA STUDENCKIE, KONFIGURACJA SERWERÓW, SYSTEMÓW I BAZ DANYCH, STRONY INTERNETOWE, POMOC W PROGRAMOWANIU, POPRAWIENIE I OPTYMALIZACJA APLIKACJI
JAVA, C++, LINUX, WWW, SQL, PYTHON
POSIADAM KOMERCYJNE DOŚWIADCZENIE
TANIO, SZYBKO I PORZĄDNIE
Z KOMENTARZAMI OBJAŚNIAJĄCYMI KOD
PISZ NA PRYWATNĄ WIADOMOŚĆ
CENY JUŻ OD 49,99ZŁ ZA PROGRAM
ZAJMIJ SIĘ TYM CO CIĘ NAPRAWDĘ INTERESUJE!
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
1

@karolinaa w klasycznym MVC:

  • widok wyświetla aktualny stan Modelu (co może wymagać użycia na przykład Observera żeby wiedzieć kiedy model się zmienił, czyli to co nazwałaś "odświeżaniem widoku przez model")
  • kontroler wywołuje akcje na modelu
  • model przechowuje stan "logiki" aplikacji
    W MVP różnica jest taka że widok nie "obserwuje" modelu, a zamiast tego to Prezenter (zmodyfikowany Kontroler) zajmuje się informowaniem Widoku o zmianie Modelu (to co nazwałas "odświeżaniem widoku przez kontroler").
    Ale nie polecam mieszać tych 2 podejść, bo trudno się potem odnaleźć w kodzie kiedy pewne operacje są w różnych miejscach w kodzie zaimplementowane w różny sposób.

"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
DZ
  • Rejestracja:około 14 lat
  • Ostatnio:około 8 lat
  • Postów:76
1
  • Widok: może korzystać ro model: TAK
  • Kontroler: może korzystać rw z modelu i odświeżać widok: NIE
  • Model: może odświeżać widok?: TAK (nawet musi)

Kontroler: jak wyżej pisałem, to pewna warstwa abstrakcji pomiędzy userem a app. Może on jedynie wywoływać metody modelu jak w powyższym kodzie, jednak już nie uczestniczy w update widoku (bo robi to model). Model "organizuje" się sam dostając parametry od kontrolera. Podsumowując kontroler pobiera z widoku i przekazuje modelowi czyli działa w trybie 'r' dla widoku i tyle.

KA
KA
  • Rejestracja:prawie 12 lat
  • Ostatnio:prawie 5 lat
  • Lokalizacja:Warszawa
  • Postów:1683
0

OK dzięki


PROGRAMY NA ZAMÓWIENIE, ZALICZENIA STUDENCKIE, KONFIGURACJA SERWERÓW, SYSTEMÓW I BAZ DANYCH, STRONY INTERNETOWE, POMOC W PROGRAMOWANIU, POPRAWIENIE I OPTYMALIZACJA APLIKACJI
JAVA, C++, LINUX, WWW, SQL, PYTHON
POSIADAM KOMERCYJNE DOŚWIADCZENIE
TANIO, SZYBKO I PORZĄDNIE
Z KOMENTARZAMI OBJAŚNIAJĄCYMI KOD
PISZ NA PRYWATNĄ WIADOMOŚĆ
CENY JUŻ OD 49,99ZŁ ZA PROGRAM
ZAJMIJ SIĘ TYM CO CIĘ NAPRAWDĘ INTERESUJE!
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)