我尝试在Firebase数据库上进行多个顺序和相关查询。 这就是数据库的样子:
books : { book1: { title: 'Book 1', author: 'author1' } }
authors: { author1: { name: 'Author 1' } }
我想要检索所有书籍,遍历它们,获取相关的作者姓名,在每个书籍对象中设置值并返回包含书籍对象的Observable数组。
我试过这种方式:
getBooks(): Observable<Book[]> {
return this._af.database
.list('/books')
.flatMap(e => e)
.concatMap(e => this.getAuthor(e.author), (a, b) => {
a.author = b.lastName;
return a;
});
}
但这只会返回第一本书。
答案 0 :(得分:0)
鉴于list(/books)
返回类似[bookObj, bookObj]
的数组,您需要获取每本书的作者信息,不需要concatMap,除非输出需要保存输入书籍。
getBooks(): Observable<Book[]> {
return this._af.database
.list('/books')
.flatMap(booksArr => Rx.Observable.from(booksArr))
.flatMap(
book => this.getAuthor(e.author),
(book,a) => {
a.author = book.lastName;
return a;
}
);
}
答案 1 :(得分:0)
由于无法使用运算符实现此功能,我创建了import UIKit
import Alamofire
import SVProgressHUD
struct postinput {
let mainImage : UIImage!
let name : String!
let author : String!
let summary : String!
let content : String!
}
class TableViewController: UITableViewController {
//var activityIndicatorView: UIActivityIndicatorView!
var postsinput = [postinput]()
var refresh = UIRefreshControl()
var mainURL = "https://www.example.com/api"
typealias JSONstandard = [String : AnyObject]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.tableView.addSubview(refresh)
//;refresh.attributedTitle = NSAttributedString(string: "Refreshing...", attributes:[NSForegroundColorAttributeName : UIColor.black])
refresh.backgroundColor = UIColor(red:0.93, green:0.93, blue:0.93, alpha:1.0)
//refresh.tintColor = UIColor.white
refresh.addTarget(self, action: #selector(self.refreshData), for: UIControlEvents.valueChanged)
//refresh.addTarget(self, action: #selector(getter: TableViewController.refresh), for: UIControlEvents.valueChanged)
refresh.attributedTitle = NSAttributedString(string: "Updated: \(NSDate())")
//activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
//tableView.backgroundView = activityIndicatorView
callAlamo(url: mainURL)
}
func refreshData() {
Alamofire.request("https://www.example.com/api").responseJSON(completionHandler: {
response in
self.parseData(JSONData: response.data!)
self.tableView.separatorStyle = UITableViewCellSeparatorStyle.singleLine
DispatchQueue.main.async {
self.tableView.reloadData()
self.refresh.endRefreshing()
}
})
}
func callAlamo(url : String){
//activityIndicatorView.startAnimating()
SVProgressHUD.show(withStatus: "Loading...")
SVProgressHUD.setDefaultStyle(SVProgressHUDStyle.dark)
SVProgressHUD.setDefaultAnimationType(SVProgressHUDAnimationType.native)
SVProgressHUD.setDefaultMaskType(SVProgressHUDMaskType.black)
Alamofire.request(url).responseJSON(completionHandler: {
response in
self.parseData(JSONData: response.data!)
self.tableView.separatorStyle = UITableViewCellSeparatorStyle.singleLine
//self.activityIndicatorView.stopAnimating()
SVProgressHUD.dismiss()
})
}
func parseData(JSONData : Data) {
do {
var readableJSON = try JSONSerialization.jsonObject(with: JSONData, options: .mutableContainers) as! JSONstandard
// print(readableJSON)
if let posts = readableJSON["posts"] as? [JSONstandard] {
for post in posts {
let title = post["title"] as! String
let author = post["author"] as! String
guard let dic = post["summary"] as? [String: Any], let summary = dic["value"] as? String else {
return
}
let str = summary.replacingOccurrences(of: "<[^>]+>", with: "", options: .regularExpression, range: nil)
print(str)
guard let dic1 = post["content"] as? [String: Any], let content = dic1["value"] as? String else {
return
}
let str1 = content.replacingOccurrences(of: "<[^>]+>", with: "", options: .regularExpression, range: nil)
print(str1)
//print(author)
if let imageUrl = post["image"] as? String {
let mainImageURL = URL(string: imageUrl )
let mainImageData = NSData(contentsOf: mainImageURL!)
let mainImage = UIImage(data: mainImageData as! Data)
postsinput.append(postinput.init(mainImage: mainImage, name: title, author: author, summary: summary, content: content))
}
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
catch {
print(error)
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return postsinput.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
// cell?.textLabel?.text = titles[indexPath.row]
let mainImageView = cell?.viewWithTag(2) as! UIImageView
mainImageView.image = postsinput[indexPath.row].mainImage
mainImageView.layer.cornerRadius = 5.0
mainImageView.clipsToBounds = true
//(cell?.viewWithTag(2) as! UIImageView).image = postsinput[indexPath.row].mainImage
let mainLabel = cell?.viewWithTag(1) as! UILabel
mainLabel.text = postsinput[indexPath.row].name
mainLabel.font = UIFont.boldSystemFont(ofSize: 18)
mainLabel.sizeToFit()
mainLabel.numberOfLines = 0;
let autLabel = cell?.viewWithTag(3) as! UILabel
autLabel.text = postsinput[indexPath.row].author
autLabel.font = UIFont(name: "Helvetica", size:16)
autLabel.textColor = UIColor(red: 0.8784, green: 0, blue: 0.1373, alpha: 1.0) /* #e00023 */
let sumLabel = cell?.viewWithTag(4) as! UILabel
sumLabel.text = (postsinput[indexPath.row].summary).replacingOccurrences(of: "<[^>]+>", with: "", options: .regularExpression, range: nil)
sumLabel.font = UIFont(name: "Helvetica", size:16)
sumLabel.textColor = UIColor(red:0.27, green:0.27, blue:0.27, alpha:1.0)
//let contentLabel = cell?.viewWithTag(0) as! UILabel
//contentLabel.text = (postsinput[indexPath.row].content).replacingOccurrences(of: "<[^>]+>", with: "", options: .regularExpression, range: nil)
//(cell?.viewWithTag(3) as! UILabel).text = postsinput[indexPath.row].author
return cell!
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
postsinput.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
via Observable
方法并在返回新数组之前执行查询:
create()
这不是我的预期,但它有效。