ngFor的异常行为 [英] Unusual behaviour of ngFor

查看:92
本文介绍了ngFor的异常行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天,我正在尝试角度指令ngFor.我面临的问题是,当我选择任何复选框(例如0)并单击下一个"时,如果下一个问题也具有与我在上一个问题中选择的选项相同的选项(0),那么它将被自动选中,我不会知识?? [如果任何两个或两个以上连续问题都没有一个相同的选择,则不会出现这种现象. ].我希望这是有道理的.这是我的朋克车

Today i was trying angular directive ngFor. The problem i am facing is that when i select any checkbox (for e.g. 0) and click "next" , if next question also have the same option (0) as i have selected in previous question then it will be checked automatically, i dont know how?? [This behaviour is not seen if any two or more consecutive questions doesnt have alteast one same option. ]. I hope it make sense. here is my plunker

模板:

    {{question}}
    <div *ngFor="let option of options">
      <input type="checkbox">{{option}}<br>
    </div>

  <button (click)="onNext()">next</button>

Component.ts

export class App implements OnInit {
    private questionPaper = {
        questions: [{
                _id: "59d1cbd4f8a709358c045696",
                question: "2 + 3",
                __v: 0,
                answers: [
                    "5"
                ],
                options: [
                    "0",
                    "1",
                    "5",
                    "3",
                    "6"
                ]
            },
            {
                _id: "59d1cbf7f8a709358c045698",
                question: "1 * 3",
                __v: 0,
                answers: [
                    "3"
                ],
                options: [
                    "1",
                    "3",
                    "0",
                    "4"
                ]
            },
            {
                _id: "59d1cc18f8a709358c045699",
                question: "3 - 3",
                __v: 0,
                answers: [
                    "0"
                ],
                options: [
                    "3",
                    "0",
                    "6",
                    "4",
                    "7"
                ]
            },
            {
                _id: "59d1cc3ef8a709358c04569a",
                question: "6 - 4",
                __v: 0,
                answers: [
                    "2"
                ],
                options: [
                    "2",
                    "3",
                    "4",
                    "0",
                    "6"
                ]
            },
            {
                _id: "59d1cc71f8a709358c04569b",
                question: "4 * 8",
                __v: 0,
                answers: [
                    "32"
                ],
                options: [
                    "4",
                    "8",
                    "12",
                    "32",
                    "23"
                ]
            },
            {
                _id: "59d1cc96f8a709358c04569c",
                question: "0 * 1",
                __v: 0,
                answers: [
                    "0"
                ],
                options: [
                    "0",
                    "1",
                    "10",
                    "-1",
                    "4"
                ]
            },
            {
                _id: "59d1cccdf8a709358c04569d",
                question: "6 + 6",
                __v: 0,
                answers: [
                    "12"
                ],
                options: [
                    "6",
                    "12",
                    "21",
                    "0"
                ]
            },
            {
                _id: "59d1fb6a253c5270115f4ced",
                question: "1 + 10",
                __v: 0,
                answers: [
                    "11"
                ],
                options: [
                    "11"
                ]
            }
        ]
    };

    private question;
    private options = [];
    private currentQuesNumber = 1;
    onInit() {}
    constructor() {
        this.question = this.questionPaper.questions[0].question;
        this.options = this.questionPaper.questions[0].options;

    }

    onNext() {

        if (this.currentQuesNumber >= this.questionPaper.questions.length) {
            this.loadQuestion(this.questions.length);

        } else {

            this.currentQuesNumber = this.currentQuesNumber + 1;
            this.loadQuestion(this.currentQuesNumber);

        }
    }



    loadQuestion(quesNumbToLoad) {
        if (quesNumbToLoad > 0 && quesNumbToLoad <= this.questionPaper.questions.length) {
            this.question = this.questionPaper.questions[quesNumbToLoad - 1].question;

            this.options = this.questionPaper.questions[quesNumbToLoad - 1].options;
        }

    }

}

推荐答案

这是缩进的行为,因为基于对象标识,角度重新使用了ngForOf指令中的DOM元素以获得更好的性能.价值.因此,在您的情况下,值是 string ,这意味着对象标识是其值.

That is the indented behavior because angular resuses DOM elements inside it's ngForOf-directive for better performance, based on the object identity of the value. So in your case the value is a string, that means the object identity is its value.

因此,如果问题之间的选项值相同,则 angular 将重用DOM元素.因为使用了相同的DOM元素,所以复选框状态仍为选中.

Therefore angular is reusing the DOM element if the value of an option is the same between questions. Because the same DOM element is used the checkbox state is still checked.

如果您希望 angular 不重用ngForOf指令中的DOM元素,则必须提供一个函数,该函数始终返回某种unqiue id(),例如当前日期时间)并将其应用于ngForOf指令(短语法trackBy)的ngForTrackBy输入.

If you want angular to not reuse DOM elements inside an ngForOf-directive, you have to provide a function which always returns some sort of a unqiue id (e.g. the current datetime) and apply it to the ngForTrackBy input of the ngForOf-directive (short-syntax trackBy).

例如:

组件

public trackById(index: number, value: any) {
  return Date.now();
}

组件模板

*ngFor="let option of options;trackBy:trackById"

或:

<ng-template ngFor let-option [ngForOf]="options"[ngForTrackBy]="trackByFn">
</ng-template>


现在,角度不再为此ngForOf指令重用任何DOM元素.


Now angular doesn't reuse any DOM elements for this ngForOf-directive.

有关ngForOf指令的更改传播的更多信息,请参见 docs (以及一些有用的其他内容).

More about the change propagation of the ngForOf-directive can be found in the docs (and some useful other stuff about it).

注意:这也可以相反的方式工作.例如,如果您有一些不可变的数据,并且不想在每次更改时都创建新的DOM元素.只需提供一个返回项目当前索引的函数即可.这将强制角度重用ngForOf指令中的每个现有DOM元素,而不考虑对象标识.

Note: This also works also the opposite way. For example if you have some immutable data and you don't want new DOM elements to be created on every change. Just provide a function which returns the current index of the item. This will force angular into reusing every existing DOM-element inside your ngForOf-directive regardless of the object identity.

这篇关于ngFor的异常行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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