我有一个拥有列表的应用程序,用户可以从列表中删除项目。
这是保存初始列表的服务,以及从所述列表中删除项目的功能:
import {Injectable} from '@angular/core';
@Injectable()
export class Services {
public items: any[] = [
{
title: 'Tarek learns Angular',
subheading: 'He now knows Angular!',
subtext: 'He adds another framework to his techstack!',
avatar: 'https://i.kym-cdn.com/entries/icons/original/000/013/564/doge.jpg',
date: 'Friday July 20th 2018',
isNewItem: true
},
{
title: 'Human throws frisbee',
subheading: 'Dog catches frisbee!',
subtext: 'Dog is a good boy!',
avatar: 'https://i.kym-cdn.com/entries/icons/original/000/013/564/doge.jpg',
date: 'Friday July 20th 2018',
isNewItem: false
},
{
title: 'Human sdfgsfsdfthrows frisbee',
subheading: 'Dog cadsfsatches frisbee!',
subtext: 'Dog is a good bvsdfvsdvoy!',
avatar: 'https://i.kym-cdn.com/entries/icons/original/000/013/564/doge.jpg',
date: 'Friday July 20th 2018',
isNewItem: false
},
{
title: 'Humavsdvsdn throsdvsdvsdvws frisbee',
subheading: 'Dog cavsddsvstches frisbee!',
subtext: 'Dog is adsvsdfeegedsf good boy!',
avatar: 'https://i.kym-cdn.com/entries/icons/original/000/013/564/doge.jpg',
date: 'Friday July 20th 2018',
isNewItem: false
}
];
numberOfNewItems: number = this.items.map(function (item) {
if (item.isNewItem) {
return item;
}
}).length;
deleteItem = (itemObj: { itemTitle: string, itemSubheading: string, itemSubtext: string, itemDate: string }) => {
const newItems: any [] = [];
let numberOfFilteredNewItems: number = 0;
const filterUndefined = this.items.map((item) => {
if (item.title !== itemObj.itemTitle && item.subheading !== itemObj.itemSubheading) {
if (item.subtext !== itemObj.itemSubtext && item.data !== itemObj.itemDate) {
return item;
}
}
});
for (const item of filterUndefined) {
if (item !== undefined) {
newItems.push(item);
if (item.isNewItem) {
numberOfFilteredNewItems++;
}
}
}
this.items = newItems;
this.numberOfNewItems = numberOfFilteredNewItems;
};
checkItemAsOld = (itemObj: { itemTitle: string, itemSubheading: string, itemSubtext: string, itemDate: string }) => {
const newItems = this.items.map((item) => {
if (item.title === itemObj.itemTitle && item.subheading === itemObj.itemSubheading && item.subtext === itemObj.itemSubtext && item.date === itemObj.itemDate) {
return {title: item.title, subheading: item.subheading, subtext: item.subtext, date: item.date, isNewItem: false};
} else {
return item;
}
});
let numberOfNewFilteredItems: number = 0;
for (const item of newItems) {
if (item.isNewItem) {
numberOfNewFilteredItems++;
}
}
this.numberOfNewItems = numberOfNewFilteredItems;
this.items = newItems;
console.log(this.numberOfNewItems);
console.log(this.items);
}
}
deleteItem
和checkItemAsOld
正常运行,并且正在更新值。每次我console.log时,它都会显示this.items
和'this.numberOfNewItems`正确更新。但是由于某种原因,视图根本没有更新。
我确保在app.module.ts
中,将服务附加到了providers
数组,并确保其他组件中没有providers
数组可以覆盖provider数组在app.modules.ts
文件中。这是app.module.ts
文件:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import {ListComponent} from './ListComponent/list.component';
import {HeaderComponent} from './HeaderComponent/header.component';
import {ItemComponent} from './ItemComponent/item.component';
import {FooterComponent} from './FooterComponent/footer.component';
import {Services} from './services';
@NgModule({
declarations: [
AppComponent,
ListComponent,
HeaderComponent,
ItemComponent,
FooterComponent
],
imports: [
BrowserModule
],
providers: [Services],
bootstrap: [AppComponent]
})
export class AppModule { }
在app.components.html
中,我像这样传递了这些项:
<app-list [items]="items" [numberOfNewItems]="numberOfNewItems"></app-list>
这是'app.component.ts`文件:
import {Component, OnInit, Input} from '@angular/core';
import {Services} from './services';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
@Input() items: { title: string, subheading: string, subtext: string, avatar: string, date: string, isNewItem: boolean }[] = [];
@Input() numberOfNewItems: number;
constructor(private listServices: Services) {
}
ngOnInit() {
this.items = this.listServices.items;
this.numberOfNewItems = this.listServices.numberOfNewItems;
}
}
我将items数组传递给了list.component.ts
文件:
import {Component, Input, EventEmitter} from '@angular/core';
import {ItemModel} from '../ItemComponent/item.model';
import {Services} from '../services';
@Component({
selector: 'app-list',
templateUrl: './list.component.html',
styleUrls: ['./list.component.css']
})
export class ListComponent {
@Input() items: any [];
@Input() numberOfNewItems: number;
constructor(private listServices: Services) {
}
}
但是即使this.items
更新,视图也不会更新。谁能帮我?我是Angular的新手。
答案 0 :(得分:1)
在您的服务中,您将在删除项目时更新列表引用(基本上将列表复制到另一个数组中,并覆盖以前的引用):
this.items = newItems;
this.numberOfNewItems = numberOfFilteredNewItems;
但不更新组件中使用的列表引用:
ngOnInit() {
this.items = this.listServices.items;
this.numberOfNewItems = this.listServices.numberOfNewItems;
}
有很多方法可以解决此问题,以使您的引用保持同步。
一种简单的方法是直接绑定到引用:
<app-list [items]="listServices.items" [numberOfNewItems]="listServices.numberOfNewItems"></app-list>
另一种方法是,只要列表发生更改,就可以从服务中公开组件可以订阅的Observable。
最后,第三个选项:保留列表引用,只需删除该项目即可。为什么在不需要时将列表重新创建为新的数组引用。
deleteItem(item: any) {
let i = this.items.indexOf(item);
if (i >= 0) {
this.items.splice(i, 1);
}
}
第三个选项可能是从列表中删除的最简单,最典型的方法。这也是我建议的选项,其次是选项2,然后是选项1。