解析云代码定义结果

Posted

技术标签:

【中文标题】解析云代码定义结果【英文标题】:Parse Cloud Code Define Results 【发布时间】:2017-10-20 05:42:15 【问题描述】:

在挣扎了很多天后,我设法从 Parse Cloud Query 中检索到我想要的结果。

我的问题是我有两个查询合并到一个,所以需要使用不同的列来显示。

我将 Ionic3/Angular 4 与 Parse Server 一起使用。

这是我的 Parse Cloud 代码

    Parse.Cloud.define('FriendsQuery', function (req, res) 
  const fromUserQ = new Parse.Query("Friends")
    .equalTo("toUser", req.user)
    .include('fromUser')
    .find();

  const toUserQ = new Parse.Query("Friends")
    .equalTo("fromUser", req.user)
    .include('toUser')
    .find();

  Parse.Promise.when(toUserQ, fromUserQ)
    .then((toUsers, fromUsers) =>
      res.success(
        toUsers: toUsers.map(e => e.get('toUser')),
        fromUsers: fromUsers.map(e => e.get('fromUser')),
      ))
    .catch(res.error);
);

满足.ts

import  Data  from './../../services/data';
import  localData  from './../../services/local';
import  Component  from '@angular/core';
import  NavController  from 'ionic-angular';
import  Parse  from 'parse';
import 'rxjs/add/operator/map';
import User from '../../models/User';
import 'rxjs/add/operator/debounceTime';
import FormControl from '@angular/forms';

@Component(
  selector: 'page-meet',
  templateUrl: 'meet.html'
)
export class MeetPage 

  currentUser = Parse.User.current();
  query = new Parse.Query(Parse.User);
  tmp =[];
  tmp2 =[];
  friends: any=[];

  initializeItems() 
  this.friends = this.localdata.tmpfriends;
  

  retrieveFriends()
   if (this.currentUser= Parse.User.current()) 
     console.log(this.currentUser.id)
     Parse.Cloud.run('FriendsQuery',currentuser: this.currentUser.id).then(
     res =>        
       console.log(res);
       this.tmp2 = res;
       this.localdata.setFriends(this.tmp2);
       this.friends = this.localdata.tmpfriends;
       console.log(this.friends);
       );            
   
   

  constructor(public navCtrl: NavController, private localdata: localData, private dataService: Data) 
    this.searchControl = new FormControl;


showFriends: any = false;
searchControl: FormControl;
searchTerm: string = '';
searching: any = false;

filterfriends(searchTerm) 
       return this.friends.filter((friend) => 
           return friend.fromUser.username.toLowerCase().indexOf(searchTerm.toLowerCase()) > -1;
       );    
    

ionViewDidLoad() 
  this.retrieveFriends();
  this.setFilteredItems();
  this.searchControl.valueChanges.debounceTime(700).subscribe(search => 
    this.searching = false;
    this.setFilteredItems();
     );


onSearchInput()
  this.searching = true;
  

setFilteredItems() 
  this.initializeItems();
  this.friends = this.filterfriends(this.searchTerm);
  

onCancel(ev: any) 
  this.initializeItems();


meet.html

  <ion-header>
  <ion-navbar>
    <ion-searchbar [(ngModel)]="searchTerm" [formControl]="searchControl" (ionCancel)="onCancel($event)" (ionInput)="onSearchInput()">
  </ion-searchbar>
  </ion-navbar>
</ion-header>

<ion-content padding>
    <div *ngIf="searching" class="spinner-container">
        <ion-spinner></ion-spinner>
    </div>
       <ion-item class="item-avatar item-avatar-left item-button-right common-list" >
            <ion-avatar *ngIf="friend.fromUser.objectId == currentUser.id" item-left><img style="left:0px !important;margin-top:0px !important;" [src]="friend.toUser.avatar  || '/assets/img/no-avatar.png'"/></ion-avatar>
            <ion-label *ngIf="friend.fromUser.objectId == currentUser.id">friend.toUser.username</ion-label>
            <ion-avatar *ngIf="friend.toUser.objectId == currentUser.id" item-left><img style="left:0px !important;margin-top:0px !important;" [src]="friend.fromUser.avatar  || '/assets/img/no-avatar.png'"/></ion-avatar>
            <ion-label *ngIf="friend.toUser.objectId == currentUser.id">friend.fromUser.username</ion-label>
            </ion-item>
</ion-content>

local.ts

import  Component  from '@angular/core';

export class localData 

    setFriends (friends)
        window.localStorage.friends_data = JSON.stringify(friends);
    
    getFriends()
       return JSON.parse(window.localStorage.friends_data || '[]');
    

    tmpfriends = this.getFriends();
       

在我的“朋友”表中,我有两列,“fromUser”和“toUser”,我想显示当前登录用户的朋友。所以在 Angular 代码中,我需要 friend.toUser.usernamefriend.fromUser.username 取决于登录的用户。

当我使用第一个时,我只获得向登录用户发送好友请求的用户的结果,反之亦然。

为了更清楚,我附上了图片链接。我不想要屏幕上的结果,而是我用箭头指向的结果。

使用 hmtl 代码我设法得到了这个结果,但是用这个过滤它们并不方便:

filterfriends(searchTerm) 
return this.friends.filter((friend) => 
return friend.fromUser.username.toLowerCase().indexOf(searchTerm.toLowerCase()) > -1;
);    
 

因为我需要同时过滤friend.toUser和friend.fromUser

screenshot

谢谢

【问题讨论】:

uh-oh: if (this.currentUser= Parse.User.current()) 几乎可以肯定没有按照您的想法行事。试试这个:if(this.currentUser.id === Parse.User.current().id) OOOOH,我想我明白你想要什么了!!!将更新我的答案,让我们看看.... 嗨亚瑟,是的,你上面提到的没有错,但是我将如何显示结果。对我来说,最好的选择是检查 Cloud Code,如果用户是 fromUser 或 toUser,以便检索最终可以在 hmtl 中作为friend.username使用的列表。我正在等待您的回复!再次感谢您! 【参考方案1】:

如果toUserfromUser 已经是用户指针,则不需要整个 "__type": "Pointer", "className": "_User", "objectId": req.params.currentuser ,您可以使用.equalTo("toUser", request.params.currentUser);。此外,如果您从已登录的客户端发出此请求,则只需执行 .equalTo("toUser", request.user);

还有一个查询方法,.include(&lt;key&gt;);,它将包含指向的对象。因此,您可以执行friendQuery.include("toUser").include("fromUser"); 并获取该信息。而且,如果您在用户上有某种附加指针,例如 ContactInfo 类,这适用于点表示法。您可以使用query.include("toUser.contactInfo");,该对象也会被包含在内。

除此之外,我不完全确定您遇到的问题是什么。什么不工作,你想工作?听起来您正在获得所需的信息。

【讨论】:

嗨,Jake。我已将云代码更改为: const query1 = new Parse.Query("Friends"); const query2 = new Parse.Query("Friends"); query1.equalTo("fromUser", req.params.currentuser); query2.equalTo("toUser", req.params.currentuser); constfriendquery = Parse.Query.or(query1, query2); friendQuery.include("toUser").include("fromUser"); friendquery.find().then((results) => res.success(results); ) .catch(() => response.error("用户查找失败"); ); );但这给了我一个 500 Post Internal Server 错误。 没有看到实际的完整代码很难说。您始终可以设置断点并逐步查看究竟是哪一行引发了内部服务器错误,或者打开异常断点并查看错误所在。您可能还会有更多的调试日志,而不仅仅是抛出可以告诉您线路/问题的错误。也只是你显示的代码的 sn-p 有一个额外的);,不确定这是否相关。 嗨,Jake,我已经编辑并添加了我现在拥有的代码 Parse Cloud Code、services 和 html。现在它正在工作,但我无法弄清楚最后一部分。【参考方案2】:

所以,如果我理解这个问题,你想要的是:

    要返回一个朋友数组,因为您并不真正关心哪个是 fromUser 哪个是 toUser,您只需要所有朋友。

    您希望此列表“删除重复数据”,因为您可能已加好友并已被同一用户加为好友,并且您不希望该列表出现两次。

    您“可能”也想过滤好友。

在单个云函数中执行此操作很有意义。

字符串匹配有点棘手。我们可以使用正则表达式和matches query 函数,但由于我们是在用户表而不是朋友表上进行匹配,所以这很棘手。为简单起见,我只是在 javascript 中过滤结果。

对于重复数据删除,我使用 lodash 库。

const fp = require('lodash/fp');

Parse.Cloud.define('FriendsQuery', function (req, res) 
  const fromUserQ = new Parse.Query('Friends')
    .equalTo('toUser', req.user)
    .include('fromUser')
    .find();

  const toUserQ = new Parse.Query('Friends')
    .equalTo('fromUser', req.user)
    .include('toUser')
    .find();

  return Parse.Promise.when(toUserQ, fromUserQ)
    .then((toUsers, fromUsers) => 
     const friendsWithDupes = toUsers.map(e => e.get('toUser'))
        .concat(fromUsers.map(e => e.get('fromUser')));
      // fp.uniquWith(comparator)(arrayToDeDupe);
      const friends = fp.uniqWith((x, y) => x.id === y.id)(friendsWithDupes);

      if (req.params.searchTerm) 
        const lowerSearchTerm = req.params.searchTerm.toLowerCase();
        const filteredFriends = friends.filter(
          friend => friend.get('username').toLowerCase().indexOf(lowerSearchTerm) > -1
        );
        return res.success(filteredFriends);
      

      return res.success(friends);
    )
    .catch(e => res.error(JSON.stringify(e)));
);

您可以使用或不使用搜索词来调用此函数:

Parse.Cloud.run('FriendsQuery', searchTerm: 'bob' )

Parse.Cloud.run('FriendsQuery')

【讨论】:

你好亚瑟,我将问题编辑得更清楚。我添加了 html 的完整代码,我现在如何显示结果和包含在我的 ts 文件中的过滤器函数。我还用第二个承诺测试了你的云代码,如果只有对象的 id,结果中。我将它们保存在本地并调用它们,然后我才能得到想要的结果。但我的主要问题是如何在不使用friend.fromUser 和friend.toUser 的情况下显示结果,以便能够全部过滤并排序。例如,简单的friend.username。十分感谢。我附上图片link 我很困惑。我不明白过滤器功能在哪里使用或用于什么目的。我也不明白你对我的云代码是什么意思,“将它们保存在本地,然后再调用它们……”。对象应该在那里。你试过results.toUser[0].get('username')吗? 感谢您对亚瑟的关注。我已经准确地添加了我使用的代码部分,以便更清晰。 嗨 Arthur,我尝试了新的 Cloud Code,但出现错误。在 html 中,我使用 friend.username 来获取好友列表。我附上图片。似乎在云代码中,我们仅在过滤器功能中返回用户名而不在结果中 [link] (imgur.com/a/ESfri) 关于搜索词,由于用户在搜索栏中输入不同的用户名,因此不稳定 2. 你有权利并不是真的,因为这不是两个用户可以互相关注的 instagram 或 twitter 的哲学。这是facebook的哲学,当一个人发送请求而另一个人接受时,他们就是朋友。第二个无法发送好友请求。所以我认为你的第二个子弹无效

以上是关于解析云代码定义结果的主要内容,如果未能解决你的问题,请参考以下文章

解析云代码嵌套查询时未调用代码 141 成功/错误消息

解析云代码之前保存未在更新时运行

使用解析云函数

解析云代码 request.object.get(key) 总是返回 undefined

解析查询不返回结果

解析云代码如何与解析服务器一起工作?