简体   繁体   English

使用 React Native 对电话联系人进行排序

[英]Sorting Phone Contacts With React Native

My react-native application sends something similar to messages to contacts in the users phonebook that have my application.我的 react-native 应用程序向拥有我的应用程序的用户电话簿中的联系人发送类似于消息的内容。 So when users register they only register to use my app, they only register their phone number.所以当用户注册时,他们只注册使用我的应用程序,他们只注册他们的电话号码。 When it comes to sending a message to a contact.在向联系人发送消息时。 I access their phonebook and compare it with numbers I have in my Rails backend.我访问他们的电话簿并将其与我在 Rails 后端中的号码进行比较。 If they match a number in the users phonebook.如果它们匹配用户电话簿中的号码。 Then I pull the name from their phone phonebook and display it to them along with the number to send a message to that contact.然后我从他们的电话簿中提取姓名并将其与号码一起显示给他们,以便向该联系人发送消息。

The issue is they are sorting randomly.问题是他们是随机排序的。 I want them to sort alphabetically.我希望他们按字母顺序排序。 The number comes from the BE (Rails) and the name comes from the FE (React-Native) app.编号来自 BE(Rails),名称来自 FE(React-Native)应用程序。 I know I need to put them both into an array of some sort on the FE and then sort them.我知道我需要将它们都放入 FE 上的某种数组中,然后对它们进行排序。 Unfortunatly my Javascript and React-Native skills are still somewhat weak.不幸的是,我的 Javascript 和 React-Native 技能仍然有些薄弱。 I know in theory what I need to do, I just can't seem to get it to work.我从理论上知道我需要做什么,但我似乎无法让它发挥作用。

I have of course left out quite a bit of the code and left in just the important parts.我当然省略了相当多的代码,只留下了重要的部分。 The first part shows the three functions "parseContacts, fetchContacts, getContactName.第一部分展示了三个函数“parseContacts、fetchContacts、getContactName。

"fetchContacts" gets the phone number from the BE. “fetchContacts”从 BE 获取电话号码。 "getContactName" gets the name from the phones phonebooks. “getContactName”从电话电话簿中获取名称。 "parseContacts" does what it says on the tin. “parseContacts”按照它在罐头上所说的做。

async parseContacts(contacts) {
    let numbers = [];
    contacts.forEach(element => {
      element.contactNumber = element.phoneNumbers[0] ? element.phoneNumbers[0].number.replace(/[^a-zA-Z0-9]/g, '') : '';
      element.phoneNumbers[0] ? numbers.push(element.phoneNumbers[0].number.replace(/[^a-zA-Z0-9]/g, '')) : null;
    });
    this.setState({ phoneContacts: contacts })
    return numbers;
  }

  async fetchContacts(contacts) {
    let phoneNumbers = await this.parseContacts(contacts);
    if (phoneNumbers.length) {
      this.setState({ isLoadingNumbers: true })
      let data = {
        "numbers": phoneNumbers,
      }
      try {
        let res = await postFunctionWithAuthToken(`${baseUrl}/contact/check`,
          JSON.stringify(data), this.state.authToken);
        if (res.response) {
          console.log('contacssssst: ', res.contact_list);
          this.setState({ contacts: res.contact_list, isLoadingNumbers: false })
        } else {
          this.setState({ isLoadingNumbers: false })
          Alert.alert('Error', `${res.error}! try again.`);
        }
      } catch (error) {
        console.log('error: ', error);
        this.setState({ isLoadingNumbers: false })
        Alert.alert('Error', 'request failed! try again.')
      }
    }
  }

  getContactName(number) {
    const { phoneContacts, countryCode } = this.state;
    if (phoneContacts.length) {
      let index = phoneContacts.findIndex(element => {
        let parsedNumber = element.phoneNumbers[0] ? element.phoneNumbers[0].number.replace(/[^a-zA-Z0-9]/g, '') : "";
        if (parsedNumber) {
          if (parsedNumber.slice(0, 1) === "0") {
            if (parsedNumber.slice(1, 2) === "0") {
              if (parsedNumber.substring(2) === number ||
                parsedNumber.substring(2).replace(`${countryCode}0`, countryCode) === number) {
                return number;
              }
            } else {
              return countryCode + parsedNumber.substring(1) === number;
            }
          } else {
            // console.log('nummm: ', parsedNumber, number);
            // return parsedNumber === number;
            if (parsedNumber === number ||
              parsedNumber.replace(`${countryCode}0`, countryCode) === number) {
              return number;
            }
          }
        }

      });
      if (Platform.OS === 'ios') {
        return index >= 0 ? phoneContacts[index].givenName : ''
      } else {
        return index >= 0 ? phoneContacts[index].displayName : ''
      }
    }
  }

The below code is where I render the name and number on the phone in a list.下面的代码是我在列表中呈现手机上的姓名和号码的地方。

            <View style={styles.container}>
              {this.state.contacts.length ?
                <FlatList
                  data={this.state.contacts}
                  extraData={this.state}
                  numColumns={1}
                  keyExtractor={(item, index) => index.toString()}
                  renderItem={({ item }) => (
                    <View style={styles.itemContainer}>
                      <View>
                        <Text style={{ color: '#000', fontSize: 20 }}>
                          {this.getContactName(item.phone_number)}</Text>
                        <Text style={{ color: '#000' }}>
                          {item.phone_number}</Text>
                      </View>
                      {item.selected ?
                        <TouchableOpacity onPress={() => this.removeContact(item)}>
                          <Icon name={"ios-add-circle"} size={26} color={primaryColor} />
                        </TouchableOpacity>
                        :
                        <TouchableOpacity onPress={() => this.selectContact(item)}>
                          <Icon name={"ios-add-circle"} size={26} color={'grey'} />
                        </TouchableOpacity>
                      }
                    </View>
                  )}
                />

Hopefully it is clear what I have done so far.希望到目前为止我所做的一切都很清楚。 What I need now I think anyway.无论如何,我现在需要什么。 Is another function to pull the name and number together and sort them before I render them.是另一个功能,可以将名称和数字放在一起并在渲染它们之前对它们进行排序。 At least thats what I think.至少我是这么认为的。 Maybe the sorting needs to be done in the render.也许排序需要在渲染中完成。 I'm not 100%.我不是 100%。 Ive been trying all sorts of ways for two days now and just can't seem to get it to sort the contacts list alphabetically.这两天我一直在尝试各种方法,但似乎无法按字母顺序对联系人列表进行排序。 Any and all help would be so greatly appreciated.任何和所有的帮助都将不胜感激。

You need to put the names into the phoneNumbers array and then sort... Currently you fetch the name of the contact when rendering the phone numbers, so there's no way to sort beforehand...您需要将姓名放入 phoneNumbers 数组中,然后进行排序...目前您在呈现电话号码时获取联系人的姓名,因此无法事先进行排序...

    if (res.response) {
      console.log('contacssssst: ', res.contact_list);
      const contacts = res.contact_list.map((contact)=>{
//Loop through the contacts and add the display name found.
          contact.displayName = this.getContactName(contact.phone_number);
          return contact;
      });
//Sort using the displayName property.
      contacts.sort((a,b)=>{
           if(a.displayName > b.displayName){
               return 1;
           }
           if(a.displayName < b.displayName){
               return -1;
           }
           return 0;
      });
      this.setState({ contacts: res.contact_list, isLoadingNumbers: false })
    }

Then in your view you can access directly item.displayName.然后在您的视图中您可以直接访问 item.displayName。

I have written the sort function real quick, not too sure if that'll sort correctly.我已经很快地编写了排序函数,不太确定它是否会正确排序。

@salketer got me very close to the right answer. @salketer 让我非常接近正确的答案。 I ended using a different way of sorting.我结束了使用不同的排序方式。 And also last setState I need to set just contacts.还有最后一个 setState 我只需要设置联系人。 Thanks again.再次感谢。

if (res.response) {
  console.log('contacts: ', res.contact_list);
    const contacts = res.contact_list.map((contact)=>{
        contact.displayName = this.getContactName(contact.phone_number);
        return contact;
    });
  contacts.sort((a, b) => a.displayName.localeCompare(b.displayName));
  console.log('contacts_returned: ', contacts);
  this.setState({ contacts, isLoadingNumbers: false })
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM