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

时间:2016-02-12 12:39:03

标签: angular

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

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

在添加和删除两个新项目之后,DOM看起来像是这样:

{{1}}

问题是li部分没有删除。有什么想法吗?

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

5 个答案:

答案 0 :(得分:13)

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

this.items.splice(index, 1);

NgFor将循环遍历您的数组项,并且会检测何时添加或删除某些内容。

Plunker

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

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

     directives: [NgFor],

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

<li *ngFor="#it of items">Any Item {{it | json}}</li>

并注意控制台中的错误:

  

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

答案 1 :(得分: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();
}

这个答案也可以帮到你:

答案 2 :(得分:1)

是的,确实是变化检测。这对我有用:

    this.items = [
        ...this.items.slice(0, index),
        ...this.items.slice(index + 1, this.items.length)
    ];

答案 3 :(得分:0)

问题可能与正确设置正向引用有关(即在声明之前你不应该使用类)。要解决此问题,您可以使用共享服务:

export class SharedService {
    public items: Array<Item>=[];

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

    public removeItem(item:Item) {
       var index = this.items.indexOf(item);
      if (index >=0) {
        this.items.splice(index,1);
      }
    }
}

使用Item构造函数/析构函数中的共享服务:

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

    @Input() public heading: string;

    constructor(public sharedService:SharedService) {
        this.sharedService.addItem(this);
    }

    ngOnDestroy() {

        this.sharedService.removeItem(this);

    }
}

还有ItemContainer

@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> = [];
    constructor(public sharedService:SharedService) {
       this.items = this.sharedService.items;
    }


}

Demo Plnkr

答案 4 :(得分:-1)

我遇到了同样的问题,即使我使用了splice或detecChange 它仍然无法正常工作 @McLac提供了像这样的改革数组的方法

this.items = [
    ...this.items.slice(0, index),
    ...this.items.slice(index + 1, this.items.length)
];
救了我的命。它完美无缺。 我的代码是这样的:

let idx = this.prds.indexOf(prd);
if(idx==-1){
  return
};
/*    it was like this before, consol.log show deleted array correctly just the UI has no change..
for(let i =0; i< this.prds.length; i++){
  if(this.prds[i]==prd){
    this.prds.splice(i,1);
    break;
  }
}
*/
this.prds = [
  ...this.prds.slice(0,idx),
  ...this.prds.slice(idx+1,this.prds.length)
];