首页 > 解决方案 > 在离子复选框上设置值并将值保存在存储中 - Ionic 4

问题描述

我正在尝试制作一个电视节目跟踪应用程序,在复选框的帮助下,我希望用户标记他/她观看的剧集。我希望使用 SQLite 存储来保存复选框值并在用户打开该节目的模式时加载它们。

使用我拥有的功能,当我单击某个复选框将该剧集添加到所选数组中时,假设我添加了 3 集作为已观看的剧集,并且我错误地取消选中了三个剧集之一,它们都从所选数组中删除. 我想解决这个问题,并且还能够在用户打开该节目的模式时将“观看”的剧集保存在存储中并获取它们的值(观看检查,而不是观看未检查)。

API 返回的每季剧集的数据如下所示: 图 1

HTML:

<button ion-button color="dark" (click)="checkAll()">Mark all as watched</button>
  <ion-item *ngFor="let episodes of seasonepisodes; let i = index;">
    <ion-thumbnail style="width: 150px; height: 100px;" slot="start">
      <img src="https://image.tmdb.org/t/p/w300{{episodes.still_path}}">
    </ion-thumbnail>
    <ion-card-subtitle>Episode {{i+1}}:
      <br>
      {{episodes.name}}
      <br>
      {{episodes.air_date}}
    </ion-card-subtitle>
    <ion-checkbox slot="end" color="dark" (ionChange)="selectEpisode(episodes)" 
    [(ngModel)]="episodes.checked"></ion-checkbox>
</ion-item>

TS:

seasonepisodes = null;
this.seasonepisodes = ((this.seasondetails || {}).episodes); (this gets only the episodes in particular season - it returns an array of objects(see Picture 1)

selected: any = [];

 checkAll(){
   for(let i =0; i <= this.seasonepisodes.length; i++) {
      this.seasonepisodes[i].checked = true;
   }
   console.log(this.seasonepisodes);
 }

  selectEpisode(data){
    if(data.checked == true) {
      this.selected.push(data);
    } else {
     let newArray = this.selected.filter(function(el) {
       return el.testID !== data.testID;
    });
     this.selected = newArray;
   }
   console.log(this.selected);
  }

谢谢

标签: angularionic-frameworkcheckboxstorageionic4

解决方案


好的,所以目前有两个问题。

取消选中无法正常工作

第一个是,为什么selected取消选中一个复选框时会删除数组中的所有条目。这似乎是因为您过滤了错误的属性。

selectEpisode(data){
  if(data.checked == true) {
    this.selected.push(data);
  } else {
    // You were checking for 'testID' which does not exist (as per Picture1 you provided)
    this.selected = this.selected.filter(el => el.id !== data.id);
  }
  console.log(this.selected);
}

将选中的数组保存到存储

这个真的没有一个正确的解决方案。最简单的方法是在每次selectEpisode()调用后保存数组并ngOnInit()从存储中加载它。

@Component({...})
export class MyComponent implements OnInit {

  selected:any = [];

  constructor(
    private storage: Storage,
  ) {}

  async ngOnInit() {
    const selectedStringified = await this.storage.get('selected');
    if (selectedStringified) {
        this.selected = JSON.parse(selectedStringified);
        console.log(this.selected);
        console.log(JSON.stringify(this.seasonepisodes));

        this.seasonepisodes = this.seasonepisodes.map(episode =>  
          this.selected.some(({id}) => episode.id === id) // if episode is in selected array 
            ? {...episode, checked: true} // Return it as a new object and check it
            : episode // else return it untouched
        )
        console.log(JSON.stringify(this.seasonepisodes));
    }
  }

  checkAll(){
    this.seasonepisodes = this.seasonepisodes.map(episode => ({...episode, checked: true}));
    this.storage.set('selected', JSON.stringify(this.selected));
  }

  selectEpisode(data){
    this.selected = data.checked
      ? this.selected.some(selected => selected.id === data.id) 
        ? this.selected // do nothing if already present
        : [...this.selected, data]
      : this.selected.filter(el => el.id !== data.id);

    this.storage.set('selected', JSON.stringify(this.selected));
  }
}

这是一个工作的Stackblitz


推荐阅读