“属性不存在类型" [英] "Property does not exist in type"

查看:94
本文介绍了“属性不存在类型"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近开始研究Angular,目前正在从事一项作业,该作业是使用半径输入制作表格.填写完表格后,我现在正在检查答案是否正确,但是在进行此检查时遇到两个错误.我想做的是从数组中删除所有不正确的答案(值= 0).

这是HTML文件:

 < form>< div class ="container" * ngFor =让问题成问题">< h4> {{question.question}}</h4>< label class ="radio" * ngFor =让问题的替代方案.替代方案">< input class ="subtotal" type ="radio" name ="{{question.question}}" value ="{{alternative.value}}">{{alternative.answer}}</label></div></form> 

这是Typescript文件:

  sumValue(){让半径= document.querySelectorAll(.subtotal:checked");if(radius.length == 11){console.log(radius);for(让index = 0; index< radius.length; index ++){console.log(radius [index] .value);if(radius [index] .value == 0){radius.splice(index,1);}}} 别的 {console.log('错误');}} 

在"console.log(radius [index] .value);"上我收到以下错误:

  [ts]类型元素"上不存在属性值". 

在"radius.splice(index,1);"上我得到:

  [ts]类型'NodeListOf< Element'上不存在属性'splice'. 

我仍然没有发布图像的声誉,但这是VSCode上的观点感谢您对解决我的问题的其他方法的任何帮助和说明,这些方法是如何仅将正确的答案留在数组中.谢谢!

解决方案

您看到的是类型错误.

调用 document.querySelectorAll 时,它返回 NodeList< Element> ,因为它不知道匹配的元素将是< input/> s.返回的内容是所有元素的基本类型,这是< input/> 的超类.

第二个问题是 NodeList 没有 splice 方法.

要解决第一个问题,可以为 radius 变量指定类型:

 让半径:NodeList< HTMLInputElement>= document.querySelectorAll(.subtotal:checked"); 

但是,在组件中使用HTML元素并不是正确的"角度方式.您不想直接在Angular组件中访问HTML元素,而是希望保持页面与其背后逻辑之间的分隔.相反,您可以使用Angular的绑定系统.更具体地说,是 ngModel :

 < form>< div class ="container" * ngFor =让问题成问题">< h4> {{question.question}}</h4>< label class ="radio" * ngFor =让问题的替代方案.替代方案">< input class ="subtotal" type ="radio" [attr.name] ="question.question" [value] ="alternative.value" [(ngModel)] ="question.answer">{{alternative.answer}}</label></div></form> 

现在,每当用户编辑输入时, question.answer 属性都会自动更新.在您的组件中,您可以遍历该结构以删除无效的替代项:

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

此代码使用的过滤方法数组以创建仅包含值不等于零的元素的数组.然后,我们可以用它替换旧的 alternatives 数组.Angular将处理页面渲染以反映数据的变化.

您可以在此处详细了解ngModel.

您还可以在此处详细了解如何使用带角度的单选按钮.

I've recently started studying Angular and I'm currently working on an assignment, which is about making a form with radius inputs. After doing the form, I'm working now on checking if the answers are correct, but I'm getting two errors when doing this check. What I'm trying to do is, to delete from the array all incorrect answers (value = 0).

This is the HTML file:

 <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>

This is the Typescript file:

  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');
    }
  }

On the "console.log(radius[index].value);" I get the following error:

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

And on "radius.splice(index, 1);" I get:

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

I still haven't reputation to post images yet, but this is the view on VSCode I appreciate any help and explanations on other ways to solve my problem which is, how to leave in the array only the answers that are correct. Thank you!

解决方案

What you are seeing is a type error.

When calling document.querySelectorAll, it returns a NodeList<Element> because it doesn't know that the matched elements are going to be <input/>s. What it returns instead is the base type for all elements, which is a super class of <input/>.

The second issue is that NodeList does not have a splice method.

To fix the first issue, you can give the radius variable a type:

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

However, your use of HTML elements in the component is not the "correct" angular way. You do not want to access HTML elements directly in your angular component - you want to maintain separation between your page and the logic behind it. Instead, you can use Angular's binding system. More specifically, 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>

Now, whenever the user edits the input, the question.answer property gets updated automatically. In your component, you can iterate over the structure to remove invalid alternatives:

sumValue(){

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

}

This code uses the filter method of an array to create an array of just the elements with values that are not equal to zero. We can then use that to replace the old alternatives array. Angular will handle rendering the page to reflect the changes in data.

You can read more about ngModel here.

You can also read more about how to use radio buttons with angular here.

这篇关于“属性不存在类型"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆