Angular a binding, jak dokladnie dziala?

0

Co chcialem osiagnac:

Zbindowac stringa i policzyc jego dlugosc

Jak oryginalnie to napisalem

    <div class="row form-row">
      <div class="form-input col">
        <textarea type="text" [(ngModel)]="messagebody"></textarea>
        <label>Message Body</label>
      </div>
    </div>
    <label>{{ messagebody.length }} characters</label>
  </ng-container>
@Component({
    selector: 'app-sms-step-editor',
    templateUrl: './sms-step-editor.component.html'
})
export class SmsStepEditorComponent implements OnInit {
    public messagebody = 'with some test text';

    ngOnInit(): void {}
}

Wiadomosc zbindowalo do messagebody.length, ale textarea nie dzialal (nie pokazywal sie tekst i nie dalo sie zrobic zadnych zmian).

Teraz kod ktory dziala

    <div class="row form-row">
      <div class="form-input col">
        <textarea type="text" name="blah" [(ngModel)]="messagebody"></textarea>
        <label>Message Body</label>
      </div>
    </div>
    <label>{{ messagebody.length }} characters</label>
    {{messagebody}}
  </ng-container>

Jak zauwazyliscie (lub nie) jedyna zmiana to bylo dodanie name atrybutu do textarea. Teraz nagle dziala bez problemow.

Dlaczego w tym oficjalnym przykladzie
https://stackblitz.com/angular/qdbpeyaxyeg?file=src%2Fapp%2Fapp.component.html

input na name (144 linijka) jest bez nazwy i dziala prawidlowo?

Nie jest to problem z textarea, jezeli wrzuce do mojego kodu input bez nazwy tez nie dziala. Chcialbym lepiej zrozumiec co sie dzieje behind the scene

1

Tak szczerze to nie ma zabardzo prawa zeby dzialalo bez name, nawet gdzies byla issue jesli chodzi o doc bo wlasnie z tego powodu nie bylo jasne czy atrybut name byl potrzebny lub nie.

Bez name moze to tylko dzialac jesli dodasz [ngModelOptions]="{standalone: true}" ng_model.ts

Ogolnie od wersji 6 chyba daje ci warning a od 7 rzuca exception, bez name jesli mnie pamiec nie myli angular nie mialby jak zbindowac ewentualne walidatory i ich bledy do odpowiedniej kontrolki, po prostu template driven form to nakladka na to jak dziala reactive form i pod spodem tworzy instancje FormControl dla kazdego ngModel, w efekcie jesli dodasz do formularza
<form ...inne attrs... #formName="ngForm">
W template za pomoca formName mozesz wyswietlac bledy itp...i powinien byc to taki sam obiekt tak jakbys go stworzyl za pomoca FormBuilder

[ngModelOptions]="{standalone: true}" jest tez uzyteczne jesli uzywasz formBuilder (reactive forms) i np z jakiegos powodu chcesz dodac kontrolke ktora bedzie bindowana bezposrednio za pomoca ngModel

Ogolnie dziala to tak ze name jest potrzebny jesli uzywas template driven forms a jest opcjonalne jesli uzywasz reactive forms za pomoca formControlName / formControl

Roznica pomiedzy formControlName a formControl jest taka ze:
formControlName:

  • uzywasz w formGroup czyli form budujesz za pomoca FormBuilder
  • formGroup + formControlName przydaje sie w nested forms przyklad

formControl:

  • mozesz uzyc z FormBuilder lub budujesz w komponencie za pomoca FormControl, tylko wtedy bez formGroup musisz podac pelny path kontrolki

Przewaznie za pomoca template driver forms mozna osiagnac te same rezultaty jak za pomoca reactive forms roznica jest w tym gdzie chcesz pisac wiecej kodu w template czy w komponencie, wiadomo ze jesli masz duzo walidacji, nested forms, kontrolki zalezne od innych to reactive forms jest po prostu mniej zagmatwane i w razie potrzeby latwiej rozszerzalne

P.S jeden z artykulow ktory dobrze opisuje jak to dziala under the hood https://blog.angular-university.io/introduction-to-angular-2-forms-template-driven-vs-model-driven/

1 użytkowników online, w tym zalogowanych: 0, gości: 1