Dodanie inputa dla podobiektu

Dodanie inputa dla podobiektu
B1
  • Rejestracja:ponad 2 lata
  • Ostatnio:10 miesięcy
  • Postów:24
0

Cześć,

Stworzyłem w Springu backened do prostej apki. Teraz chce dorobić do niej front w Angularze i napotkałem następujący problem:

  1. W backendzie używam relacji @OneToMany i obsługuję metodę POST, którą przyjmuje w postmanie następujący request.

    Kopiuj
    {
            "id": 1,
            "taskName": "Creating models",
            "description": "developing models of data",
            "taskDate": "2022-12-17T11:00:00",
            "group": {
                "id": 4,
                "taskGroupName": "Programming"
            },
            "done": false
        }
    
    
  2. Teraz chcę w Angularze zrobić input i za pomocą metody POST wysłać dane do backendu. Wszystkie podstawowe pola działają prawidłowo, jednak w przypadku group dostaję błąd. Zdefiniowałem sobie w Angularze model danych:

    Kopiuj
    export interface Task {
      id: number;
      taskName: String;
      description: String;
      isDone: boolean;
      taskDate: Timestamp<any>;
      group: {
        id: number;
        taskGroupName: String;
      };
    
    
  3. Chcę zrobić Input w postaci dla wszystkich pól (tutaj wrzucam tylko dla id grupy, bo konkretnie to mi nie działa):

    Kopiuj
    <input type="text" ngModel="{{modelAdd.group.id}}" name="group.id" class="form-control" id="inputgroupb2" aria-describedby="title" placeholder="taskgroupId">
    

    Jednak dostaję błąd, że group.id jest 'undefined'.
    Dlaczego nie mogę w ten sposób pobrać danych w postaci inputa. Dodam tylko, że w analogiczny sposób metoda GET pozwala mi na wyświetlanie danych związanych z grupą:

    Kopiuj
    <div *ngFor="let task of tasks">
      <div>{{task.id}} {{task.taskName}} {{task.taskDate}} {{task.isDone}}  {{task.group.id}} {{task.group.taskGroupName}}</div>
    </div>
    

    i działa to poprawnie.

  4. Kod w szablonie wygląda mniej więcej tak:

    Kopiuj
    <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
       Launch demo modal
     </button>
    
    <!--  MODAL WINDOW ADD-->
     <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
       <div class="modal-dialog" role="document">
         <div class="modal-content">
           <div class="modal-header">
             <form #addForm="ngForm">
               <h5 class="modal-title" id="exampleModalLabel">Edit task group with Id: <b>{{modelAdd.id}}</b></h5>
               <div class="form-group">
    <!--              <label for="inputTaskName2"></label>-->
                 <input type="text" ngModel="{{modelAdd.taskName}}" name="taskName" class="form-control" id="inputTaskName2" aria-describedby="title" placeholder="Task name">
    <!--              <input type="text" ngModel="{{modelAdd.taskDate}}" name="taskDate" class="form-control" id="inputTaskDate2" aria-describedby="title" placeholder="Task date">-->
                 <input type="text" ngModel="{{modelAdd?.group.id}}" name="group.id" class="form-control" id="inputgroupb2" aria-describedby="title" placeholder="taskgroupId">
    <!--              <input type="text" ngModel="{{modelAdd.group?.taskGroupName}}" name="taskGroupName" class="form-control" id="inputgroupa2" aria-describedby="title" placeholder="taskGroupName">-->
    <!--              <input type="text" ngModel="{{modelAdd.description}}" name="description" class="form-control" id="inputTaskdescription2" aria-describedby="title" placeholder="Task description">-->
    <!--              <input class="form-control" name="id" ngModel="{{modelAdd.id}}" id="id" [defaultValue]="modelAdd.id" type="hidden">-->
               </div>
               <div class="modal-footer">
                 <button type="button" id="" data-dismiss="modal" class="btn btn-secondary">Close</button>
                 <button (click)="onAddTask(addForm.value)" data-dismiss="modal" class="btn btn-primary" >Save changes</button>
               </div>
             </form>
           </div>
         </div>
       </div>
     </div>
    
  5. Jak za pomocą takich inputów pobrać dane od użytkownika i stworzyć następujący request: (pola id, taskname, description, taskDate, done działają poprawnie jak to zrobię w ten sposób, pola związane z group już są undefined tak jakby ich nie dostawał). Co robię źlę? Jak zrobić to poprawnie? Chodzi o to, że ngModel="{{modelAdd.description}}" działa, ale już ngModel="{{modelAdd.group.id}}" dla mojego modelu danych nie działa.

    Kopiuj
    {
         "id": 1,
         "taskName": "Creating models",
         "description": "developing models of data",
         "taskDate": "2022-12-17T11:00:00",
         "group": {
             "id": 4,
             "taskGroupName": "Programming"
         },
         "done": false
     }
    
edytowany 3x, ostatnio: Riddle
FG
  • Rejestracja:około 5 lat
  • Ostatnio:około miesiąc
  • Postów:57
0

Jak dostajesz odpowiedź z backendu to masz prawidłowo utworzony obiekt JSON i pole group automatycznie ci się zmapuje na obiekt. Jak robisz formularz dodawania to musisz go sobie sam odpowiednio utworzyć, a na defaulcie pole group zainicjuje się wartością undefined.
Pokaż czym jest modelAdd i jak go inicjalizujesz

edytowany 1x, ostatnio: FrontendGuy
B1
  • Rejestracja:ponad 2 lata
  • Ostatnio:10 miesięcy
  • Postów:24
0
FrontendGuy napisał(a):

Jak dostajesz odpowiedź z backendu to masz prawidłowo utworzony obiekt JSON i pole group automatycznie ci się zmapuje na obiekt. Jak robisz formularz dodawania to musisz go sobie sam odpowiednio utworzyć, a na defaulcie pole group zainicjuje się wartością undefined.
Pokaż czym jest modelAdd i jak go inicjalizujesz

Mam pliku .ts dla tego komponentu mam to zdefiniowane tak:

Kopiuj
 modelAdd: Partial<Task> = {};

Korzysta z tego metoda, która odwołuje się do serwisu, w którym mam obsługę wszystkich metod HTTP

Kopiuj
 onAddTask(addFrom: Partial<Task>)
  {   
     this.http.postTasks(this.modelAdd as Task).subscribe((response: Task) => {this.getTaskwithDate()})
  }

AD 1. No i tak, rozumiem o co chodzi. Potrafię zrobić formularz dla prostego obiektu, gdzie w pierwotnej tabeli nie ma żadnych relacji/odwołań do innych obiektów tylko proste pola do uzupełnienia.

Wtedy robię to prostym inputem:

Kopiuj
<input type="text" ngModel="{{modelAdd.taskName}}" name="taskName" class="form-control" id="inputTaskName2" aria-describedby="title" placeholder="Task name">

Ale nie bardzo wiem, jak powinien wyglądać input dla takiej struktury:

Kopiuj
export interface Task {
  id: number;
  taskName: String;
  description: String;
  isDone: boolean;
  taskDate: Timestamp<any>;
  group: {
    id: number;
    taskGroupName: String;
  };

Pola id, taskName, description, isDone, taskDate mogę dodać formularzem z inputami jak pkt AD1.
Ale jak powinien wyglądać input w formularzu (co ma być w ngModel={{}} i name="", bo te dwa pola sa tutaj najważniejsze), żeby uzupełnić pola id, taskGrupName?
To co zaproponowałem w pierwszym poście nie działa i nie bardzo wiem dlaczego: ngModel="{{modelAdd?.group.id}}" name="group.id".
Jak dla mnie to cała metoda itd działa dobrze, problem jest w tym, że nie wiem jak zrobić poprawnie input'y w formularzu dla tych dwóch pól.
Proszę o pomoc, jak ktoś ma jakiś pomysł, bo już trochę nie wiem jak to ruszyć.

edytowany 3x, ostatnio: Batman109
FG
  • Rejestracja:około 5 lat
  • Ostatnio:około miesiąc
  • Postów:57
1

Zamień sobie:

Kopiuj
modelAdd: Partial<Task> = {};

na

Kopiuj
modelAdd: Partial<Task> = {
     "id": 1,
     "taskName": "Creating models",
     "description": "developing models of data",
     "taskDate": "2022-12-17T11:00:00",
     "group": {
         "id": 4,
         "taskGroupName": "Programming"
     },
     "done": false
 }

i zobacz rezultat.
Liczę, że to Cię naprowadzi :)

B1
  • Rejestracja:ponad 2 lata
  • Ostatnio:10 miesięcy
  • Postów:24
0

Cześć,

@FrontendGuy: Dzięki, trochę mi to zajęło, ale w końcu zrobiłem tak jak napisałeś i udało mi się rozwiązać problem.
Nie wiem czy to jest zgodnie ze sztuką, ale zamiast korzystać bezpośrednio z modelu Task, zadeklarowałem:

Kopiuj
group: {id: number, taskGroupName: String} = {id: 1, taskGroupName: "random"};

i zrobiłem inputy, który przypisuje wartości do tego:

Kopiuj
 <input type="text" [(ngModel)]="group.id" class="form-control" name="group.id" placeholder="taskgroupId">
 <input type="text" [(ngModel)]="group.taskGroupName" class="form-control" name="taskGroupName" placeholder="taskGroupName">

i na końcu, już w metodzie przypisałem zapodane w inpucie wartości do mojego modelu Taska:

Kopiuj
this.modelAdd.group = {id: this.group.id, taskGroupName: this.group.taskGroupName};

Działa ! :-)

Tylko skoro już lepiej lub gorzej udało mi się rozwiązać problem. Mógłbyś mi wyjaśnić jakoś teoretycznie dlaczego to wcześniej nie działało?
No, bo rozumiem, że jak się poda tylko ID, albo tylko taskGroupName to to nie zadziała rzeczywiście. Ja podawałem tylko jedną z tych wartości.

Ale nadal nie rozumiem dlaczego mogłem zrobić coś takiego i to działało (dostawałem id grupy dla modelu Taska):

Kopiuj
<div *ngFor="let task of tasks">
  <div>{{task.group.id}}</div>
</div>

Ale przypisanie wartości w inpucie już nie działało i dawało mi wartość undefined:

Kopiuj
<input type="text" ngModel="{{modelAdd.group.id}}" name="group.id" class="form-control" id="inputgroupb2" aria-describedby="title" placeholder="taskgroupId">


Jakie jest teoretyczne wyjaśnienie tego, bo niby zrobiłem, działa. Coś tam "świta", ale jakby mnie ktoś spytał, żebym własnymi słowami wyjaśnił czemu powyższe nie działa to taki na 100% bym nie był pewien co mu odpowiedzieć?

FG
  • Rejestracja:około 5 lat
  • Ostatnio:około miesiąc
  • Postów:57
0

Fajnie, że się udało :)

Odpowiedź z serwera zawierała już obiekt group z polami id i taskGroupName natomiast podczas dodawania SAM tworzyłeś sobie model, który miał niezdefiniowane pole 'group'.

Odpowiedź z serwera:

Kopiuj
modelAdd: Partial<Task> = {
     "id": 1,
     "taskName": "Creating models",
     "description": "developing models of data",
     "taskDate": "2022-12-17T11:00:00",
     "group": {
         "id": 4,
         "taskGroupName": "Programming"
     },
     "done": false
 }

masz tam pole group:

Kopiuj
"group": {
         "id": 4,
         "taskGroupName": "Programming"
     }

Twój model podczas dodawania:

Kopiuj
modelAdd: Partial<Task> = {};

Twoje pole 'group' = undefined

edytowany 1x, ostatnio: FrontendGuy
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)