在Angular 6中视图未更新

时间:2018-07-22 18:51:56

标签: angular

我有一个拥有列表的应用程序,用户可以从列表中删除项目。

这是保存初始列表的服务,以及从所述列表中删除项目的功能:

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

  }
}

deleteItemcheckItemAsOld正常运行,并且正在更新值。每次我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的新手。

1 个答案:

答案 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。