javascript - "Ominaisuutta ei ole tyypissä"


Olen äskettäin aloittanut Angularin opiskelun ja työskentelen tällä hetkellä tehtävän parissa, joka liittyy lomakkeen tekemiseen säteen syötteillä. Lomakkeen tekemisen jälkeen työskentelen nyt sen tarkistamisen parissa, ovatko vastaukset oikein, mutta saan kaksi virhettä tehdessäni tätä tarkistusta. Yritän poistaa taulukosta kaikki väärät vastaukset (arvo=0).

Tämä on HTML-tiedosto:

 <form>
  <div class="container" *ngFor = "let question of questions">
    <h4>{{question.question}}</h4>
    <label class="radio" *ngFor="let alternative of question.alternatives">
      <input class="subtotal" type="radio" name="{{question.question}}" value="{{alternative.value}}"> {{alternative.answer}}
    </label>
  </div>
</form>

Tämä on Typescript-tiedosto:

  sumValue(){
    let radius = document.querySelectorAll(".subtotal:checked");
    if(radius.length == 11){
      console.log(radius);
      for (let index = 0; index < radius.length; index++) {
        console.log(radius[index].value);
        if(radius[index].value == 0){
          radius.splice(index, 1);
        }
      }
    } else {
      console.log('error');
    }
  }

Komennolla "console.log(radius[index].value);" saan seuraavan virheen:

[ts] Property 'value' does not exist on type 'Element'.

Ja kohdassa "radius.splice(index, 1);" saan:

[ts] Property 'splice' does not exist on type 'NodeListOf<Element'.

Minulla ei ole vielä mainetta kuvien julkaisemiseen, mutta tässä on näkymä VSCode:ssa. Arvostan kaikenlaista apua ja selityksiä muihin tapoihin ratkaista ongelmani, joka on, kuinka jättää taulukkoon vain ne vastaukset, jotka ovat oikein. Kiitos!

Vastaus #1

Mitä näet, on tyyppivirhe.

Kun kutsutaan document.querySelectorAll, se palauttaa NodeList<Element>, koska se ei tiedä, että vastaavat elementit tulevat olemaan <input/> -elementtejä. Sen sijaan se palauttaa kaikkien elementtien perusluokan, joka on <input/>:n yläluokka.

Toinen ongelma on, että NodeList-objektilla ei ole splice-metodia.

Korjataksesi ensimmäisen ongelman, voit antaa radius-muuttujalle tyypin:

let radius: NodeList<HTMLInputElement> = document.querySelectorAll(".subtotal:checked");

Kuitenkin HTML-elementtien käyttö komponentissa ei ole "oikea" Angular-tapa. Et halua käyttää HTML-elementtejä suoraan Angular-komponentissasi - haluat säilyttää eron sivusi ja sen takana olevan logiikan välillä. Sen sijaan voit käyttää Angularin sidontajärjestelmää. Tarkemmin sanottuna ngModel:

 <form>
  <div class="container" *ngFor = "let question of questions">
    <h4>{{question.question}}</h4>
    <label class="radio" *ngFor="let alternative of question.alternatives">
      <input class="subtotal" type="radio" [attr.name]="question.question" [value]="alternative.value" [(ngModel)]="question.answer"> {{alternative.answer}}
    </label>
  </div>
</form>

Nyt aina, kun käyttäjä muokkaa syötettä, question.answer-ominaisuus päivitetään automaattisesti. Komponentissasi voit käydä läpi rakenteen poistaaksesi virheelliset vaihtoehdot:

sumValue(){

    this.questions.forEach(question => {
        question.alternatives = question.alternatives.filter(a => a.value != 0);
    });

}

Tämä koodi käyttää taulukon filter-metodia luodakseen taulukon, joka sisältää vain ne elementit, joiden arvot eivät ole nollia. Voimme sitten käyttää sitä korvaamaan vanhan alternatives-taulukon. Angular hoitaa sivun piirtämisen siten, että se heijastaa muutoksia tietoihin.

Voit lukea lisää ngModelista täältä.

Voit myös lukea lisää siitä, miten käyttää radiopainikkeita Angularin kanssa tästä.