Ionic/Firebase-错误拼接不是函数(reorderArray) [英] Ionic / Firebase - error splice is not a function (reorderArray)

查看:103
本文介绍了Ionic/Firebase-错误拼接不是函数(reorderArray)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经打了几天头...试图使用(ionItemReorder)="reorderItems($ event)"对列表进行重新排序.我有从FireBase获得的歌曲列表.当我触发reOrderItems click事件时,出现错误:TypeError:array.splice不是reorderArray上的函数

I have beat my head for a couple days...trying to use the (ionItemReorder)="reorderItems($event)" to reorder a list. I have a list of songs I'm getting from FireBase. When I fire the reOrderItems click event I get an error: TypeError: array.splice is not a function at reorderArray

我认为在定义歌曲"的方式上可能很简单.我尝试了几种不同的方法...但是目前为止,我只是在吸管.

I assume it's probably something very simple in the way I'm defining "songs". I have tried several different ways...but at this point I'm just grasping at straws.

任何建议将不胜感激.谢谢! ER

Any suggestions would be greatly appreciated. Thank you! ER

打字稿:

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, reorderArray } from 'ionic-angular';
import { AngularFireModule} from 'angularfire2';
import { AngularFireDatabase } from 'angularfire2/database';

@IonicPage()
@Component({
  selector: 'page-songs',
  templateUrl: 'songs.html',
})
export class SongsPage {

  //songs: any = {};
  //songs = {};
  //songs = [];
  //songs: any = [];
  songs: any;  
  btnName: any = 'Reorder';
  flag: any = false;

  constructor(
    public navCtrl: NavController, 
    public navParams: NavParams,
    public afd: AngularFireDatabase
  ) 
  {    
    this.songs = this.afd.list('/songs/').valueChanges();    
  }

  //Button in navbar to toggle reordering the list of songs
  actionBtn(){
    if (this.btnName == 'Reorder') {
      this.btnName = 'Done';
      this.flag = true;
    }
    else{
      this.btnName = 'Reorder';
      this.flag = false;
    }
  };

  reorderItems(indexes){
    //let element = this.songs[indexes.from];
    //this.songs.splice(indexes.from, 1);
    //this.songs.splice(indexes.to, 0, element);
    this.songs = reorderArray(this.songs, indexes);    
   };

  showChords(song){
    this.navCtrl.push('ChordsPage', song)
  }

}

HTML :

<ion-header>
  <ion-navbar>
    <ion-title>Songlist</ion-title>
    <ion-buttons end>
      <button ion-button small clear (click)="actionBtn();">
        {{btnName}}
      </button>
    </ion-buttons>
  </ion-navbar>
</ion-header>

<ion-content>
    <ion-list reorder="{{flag}}" (ionItemReorder)="reorderItems($event)">
        <ion-item-sliding *ngFor="let song of songs | async ; let i = index">

          <ion-item>
              <h2>{{i+1}}. {{ song.Title}}</h2>
              <p>{{song.Artist}}</p>        
          </ion-item>                

          <ion-item-options side="right">
              <button ion-button (click)="showChords(song)">Chords</button>
            </ion-item-options>

            <ion-item-options side="left">
                <button ion-button color="danger" (click)="removeSong(song)">Delete
                  <ion-icon name="trash"></ion-icon>
                </button>
            </ion-item-options>

              </ion-item-sliding>
      </ion-list>
</ion-content>

推荐答案

我现在又回来了,但是这是我试图解释如何使它工作的尝试.
**注意-我是一名业余编码员,所以如果我解释使用错误的术语或者如果我只是理解不正确,我会向您道歉.代码有效:).

I am late getting back to this but here is my attempt at explaining how I got this working.
**Caveat - I am a hobbyist coder so I apologize in advance if I'm explaining using wrong terms or if I just understand it wrong..the code works:).

目标是使用新版本的Firebase从Firebase获取列表并将其拉入数组,以便我可以将其显示在屏幕上,然后使用reorderArray函数在移动项目后将数组索引保持顺序在列表中.因此,如果我有一组歌曲...我将其命名为songList(认为还没有Firebase),并假定这是我的HTML:

The goal is to get a list from Firebase using the NEW version of Firebase and pull it into an array so that I can present it to the screen and then use the reorderArray function to keep the array indexes in order after moving items around in a list. So if I have an array of songs...I'll call it songList (think no Firebase yet) and assume this is my HTML:

<ion-list reorder="true" (ionItemReorder)="reorderItems($event)">
    <ion-item *ngFor="let song of songList; let i = index">
    {{i+1}}. {{song.title}} - {{song.artist}}
    </ion-item>
  </ion-list> 

然后我有标准功能来对数组重新排序:

Then I have the standard function to reorder the array:

reorderItems(indexes) {        
    this.songList = reorderArray(this.songList, indexes);    
  };

将'reorderArray'添加到导入中以启用此功能:

Add the 'reorderArray' to the import to enable this:

import { NavController, AlertController, reorderArray } from 'ionic-angular';

在仔细研究了一下之后,我认为reorderArray函数执行了一些.splice命令以使索引在数组中移动.

After looking into this a little I think the reorderArray function does a few .splice commands to get the indexes moved around in the array.

如此快速地将我的阵列替换为Firebase列表.请参阅第一篇文章中的所有上述代码...所有这些都可以使列表显示在HTML页面上.但是,一旦reorderArray被触发,我就会抛出拼接"错误.事实证明,此时的Firebase列表是一个对象,reorderArray需要一个数组.我从YouTube视频中获得了以下代码:

So fast forward to replacing my array with a Firebase list. See all the above code from the 1st post...all that works to get the list to show up on the HTML page. But as soon as the reorderArray is fired I get "splice" errors thrown. As it turns out the Firebase list at this point is an object and the reorderArray expects an array. I got the below code from a Youtube video:

//Set up the songList array
    var x = this.afDatabase.list('/songs');
    x.snapshotChanges().subscribe(item => {
      this.songList = [];
      item.forEach(element => {        
        var y = element.payload.toJSON();
        y["fbKey"] = element.key;
        this.songList.push(y);
      })
    })

我将尽力解释这是什么.我将x设置为Firebase列表/歌曲的参考.我调用snapShotChanges()以获取列表值和键.然后,我订阅列表以浏览项目.我将setList声明为数组.我遍历项目列表,我猜有效载荷"是一个特殊的属性,可以获取所有对象数据?我想我将所有对象数据都转换为数组.我将新字段添加到我认为的列表中,这样我就可以从字段中获取.key值了吗?然后,我将所有数据推送到一个数组中.

I will try to explain as best I can what this is doing. I set x to be a ref to my Firebase list /songs. I invoke snapShotChanges() to get my list values and the key. I then subscribe to the list to walk through the items. I declare setList as an array. I iterate over the list of items and I guess 'payload' is a special property that gets all the object data?? I think I cast all that object data into an array. I add a new field to the list I think so I can get back at the .key value from a field? I then push all that data into an array.

我仍然不确定所有这些魔术如何起作用,但它确实起作用.现在,在songList中有一个数组,可以保存我的所有数据...现在,我可以使用reorderArray函数在重新排序后将索引直接保持在客户端.

Again I'm not sure how all this magic works but it does. Now I have an array in songList that holds all my data...and now I can use the reorderArray function to keep the indexes straight on the client side after a reorder.

但是...新问题. Firebase列表中没有该索引值的客户端表示.

But...new problem. There is no client side representation of that index value out in the Firebase list.

这段代码的其余部分有些模糊,因为事情开始起作用时,我到处都是地图,并添加了很多东西来查看它是否起作用.现在,我遇到了Ionic Serve问题,并且如果不将其部署到Firebase或Ionic View上,就无法立即运行它,所以我必须按时记忆.

The rest of this code is a little hazy as when things started working I was all over the map and adding lots of stuff to see it work. Right now I'm having Ionic Serve issues and can't get this running right now without deploying it up to Firebase or Ionic View...so I have to go by memory.

这就是我最终的HTML外观:

So here is what my final HTML looks like:

<ion-list reorder="true" (ionItemReorder)="reorderItems($event)">
    <ion-item *ngFor="let song of songList | orderBy: 'sortOrder'; let i = index">
    {{i+1}}. {{song.title}} - {{song.artist}} ({{song.sortOrder}})
    </ion-item>
  </ion-list>  

这里唯一真正的区别是,我在一个名为sortOrder的新字段上有一个orderBy.

The only real difference here is that I have an orderBy on a new field called sortOrder.

这是所有工作的原理:

reorderItems(indexes) {  
    var luTitle = '';
    var luArtist = '';

    this.songList = reorderArray(this.songList, indexes);

    this.songList.forEach( song => {
      this.afDatabase.database.ref('songs/' + song.fbKey + '/sortOrder').set(this.songList.indexOf(song));

      this.afDatabase.database.ref('songs/' + song.fbKey)
      .on('value', function(snapshot) {
        luTitle = snapshot.child('title').val();
        luArtist = snapshot.child('artist').val();
      })

      console.log("Index: " + this.songList.indexOf(song));      
//      console.log("Title: " + song.title);      
      console.log("LU Title: " + luTitle);      
      console.log("LU Artist: " + luArtist);      
      console.log("FB Key: " + song.fbKey);  
      console.log("Sort Order: " + song.sortOrder); 
    })  
  };

很多只是将内容记录到控制台,但真正的工作是这样:

A lot of this is just logging stuff to the console but the real work is this:

我要做的第一件事是在this.songList上运行reorderArray,它将所有索引放在客户端的正确位置.然后,我遍历该数组中的所有项目,并使用在将初始FB列表转换为数组时设置的song.fbKey创建对FB列表的引用.然后,我为该歌曲设置一个sortOrder字段,该字段等于该歌曲在当前时刻存在于客户端的当前索引.在那之后我想的所有其他事情就是我将内容记录到控制台以查看值. LU(Look Up)只是我自己弄清楚如何从Firebase取回价值.

The first thing I do is run the reorderArray over the this.songList and it gets all the indexes in the right place on the client side. Then I iterate over all the items in that array and I create a reference to the FB list using the song.fbKey that we set when we converted the initial FB list to an array. Then I .set a sortOrder field for that song equal the the current index of that song as it exists on the client side at that moment in time. Everything else I think after that is me logging stuff to the console to look at values. The LU (Look Up) stuff was just me figuring out how to get a value back in from Firebase.

现在,ngFor中的orderBy立即通过sortOrder字段立即订购所有商品,这些商品基本上是从FB实时获得的.我不记得了,但是我认为如果列表是FB的全新列表,并且没有sortOrder字段,但默认情况下是按键排序...这很好...第一次重新排序时,所有sortOrders都会被设置

Now the orderBy in the ngFor immediately orders everything by the sortOrder field that basically comes in real time from FB. I can't remember but I think if the list is brand new from FB and there is no sortOrder field yet it defaults to sorting by the key...which is fine...the first time reorder is fired all the sortOrders get set.

我敢肯定,当我回到这时会发现一些错误...但是到目前为止,它仍在正常工作.

I'm sure there are some bugs I will discover when I get back to this...but it's working code as of now.

如果您能读到这么多,谢谢阅读.

Thanks for reading if you made it this far.

ER

这篇关于Ionic/Firebase-错误拼接不是函数(reorderArray)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆