Angular2 - ngFor指令不映射已删除的项目

McL*_*Lac 5 angular

我有一个Item容器和项目模式,其中应该添加子项目并从其容器中删除.添加很好,而删除什么都不做.当删除任何子项时,angular2*ngFor指令似乎不起作用.

    import { NgFor} from 'angular2/common';
    import { bootstrap } from 'angular2/platform/browser';
    import { Component, View, Directive, OnDestroy, Input, enableProdMode } from 'angular2/core';
    import { CORE_DIRECTIVES} from 'angular2/common';


    @Component({selector: 'itemcontainer',})
    @View({ template: `<ul (click)="$event.preventDefault()">
                       <li *ngFor="#it of items">Any Item</li>
                       </ul>
                       <div><ng-content></ng-content></div>`,

            directives: [NgFor],
    })
    export class ItemContainer {
        public items: Array<Item> = [];

        public addItem(item: Item) {
            this.items.push(item);
        }

        public removeItem(item: Item) {
            var index = this.items.indexOf(item);
            if (index === -1) {
                return;
            }

            console.log(`Index about to remove: ${index} this.items length: ${this.items.length}`);
            this.items.slice(index, 1);
            console.log(`this.items length: ${this.items.length}`);
        }
    }

    @Directive({ selector: 'item' })
    export class Item implements OnDestroy {

        @Input() public heading: string;

        constructor(public itemcontainer: ItemContainer) {
            this.itemcontainer.addItem(this);
        }

        ngOnDestroy() {
            this.itemcontainer.removeItem(this);
        }
    }

    @Component({
        selector: 'my-app'
    })
    @View({
        template: `<div (click)="$event.preventDefault()">
            <button type="button" (click)="addItem()">Add item</button>
            <button type="button" (click)="removeItem()">Remove item</button>

        <itemcontainer>
            <item *ngFor="#containerItem of containerItems" [heading]="containerItem.title">Content </item>
        </itemcontainer>
    </div>`,

        directives: [CORE_DIRECTIVES, Item, ItemContainer],

    })

    class Tester {

        private counter: number = 2;

        public containerItems: Array<any> = [
            { title: 'Item1' },
            { title: 'Item2' },
        ];

        addItem() {
            this.containerItems.push({ title: `Item ${this.counter}` });
        }

        removeItem() {

            if (this.containerItems.length > 0) {
                this.containerItems.splice(this.containerItems.length - 1, 1);
            }
        }
    }

    enableProdMode();
    bootstrap(Tester);
Run Code Online (Sandbox Code Playgroud)

在添加和删除两个新项目之后,DOM就像这样:

    <itemcontainer>
        <ul>
            <li>Any Item</li>
            <li>Any Item</li>
            <li>Any Item</li>
            <li>Any Item</li>
        </ul>
        <div>
            <item>Content </item>
            <item>Content </item>
        </div>
    </itemcontainer>
Run Code Online (Sandbox Code Playgroud)

问题是li部分没有删除.任何的想法?

(我用角度2.0.0-beta.3和2测试了它.)

Mar*_*cok 13

您需要使用splice()slice().这里的角度变化检测没有问题.

this.items.splice(index, 1);
Run Code Online (Sandbox Code Playgroud)

NgFor 将循环遍历您的数组项目,它将检测何时添加或删除某些内容.

Plunker

此外,你可以删除这些东西:

import { NgFor} from 'angular2/common';
import { CORE_DIRECTIVES} from 'angular2/common';

     directives: [NgFor],
Run Code Online (Sandbox Code Playgroud)

此外,您的数据中包含循环引用.将您的代码更改为以下内容

<li *ngFor="#it of items">Any Item {{it | json}}</li>
Run Code Online (Sandbox Code Playgroud)

并注意控制台中的错误:

EXCEPTION:TypeError:在[Any Item {{it |.}中将循环结构转换为JSON 在ItemContainer中的json}}


Thi*_*ier 3

事实上,Angular2 仅在实例发生变化时才检测到变化。我的意思是数组的实例不会在元素内部发生变化。

您可以使用它(请参阅第二个slice调用):

public removeItem(item: Item) {
  var index = this.items.indexOf(item);
  if (index === -1) {
    return;
  }

  console.log(`Index about to remove: ${index} this.items length: ${this.items.length}`);
  this.items.slice(index, 1);
  console.log(`this.items length: ${this.items.length}`);

  this.items = this.items.slice();
}
Run Code Online (Sandbox Code Playgroud)

这个答案也可以帮助您:

  • 由于使用了“ngFor”,Angular 更改检测会注意到何时添加或删除项目。这里的变更检测没有问题。使用“splice()”而不是“slice()”可以轻松解决该问题。详情请参阅我的回答。 (3认同)