【问题标题】:Publish results of an API call to a collection in Meteor将 API 调用的结果发布到 Meteor 中的集合
【发布时间】:2018-01-31 09:07:05
【问题描述】:

我正在尝试制作一个简单的 RSS 提要阅读器,它允许用户在搜索栏中输入网址并使用 Meteor 和 React 显示结果。在我当前的设置中,我有一个 SearchBar 组件,它带有一个调用服务器上的流星方法的函数。如何将 API 调用的返回存储在客户端集合中?我已经看到了一些使用发布和订阅来执行此操作的示例,但无法遵循。我的目标是将这些数据保存在客户端集合中,这样我就可以从任何需要它的组件中访问它,而不必通过 SearchBar 组件的 render 方法呈现后续组件。这是我目前的设置方式:

feeds.js

import { Meteor } from 'meteor/meteor';
import { HTTP } from 'meteor/http';
import parser from 'rss-parser';

if(Meteor.isServer) {
    Meteor.methods({
        getFeed(url) {
            this.unblock();
            const feed = {
                title: '',
                entries: []
            };
            try {
                console.log('trying to get url');
                const response = HTTP.get(url);
                parser.parseString(response.content, function(err, parsed) {
                  feed.title = parsed.feed.title;
                  parsed.feed.entries.forEach(function(entry) {
                    feed.entries.push(entry);
                  })
                });
                console.log(feed.title);
                return feed;
            } catch(e) {
                return false;
            }
        }
    });
}

SearchBar.js

import React, { Component } from 'react';
import { Tracker } from 'meteor/tracker';

import FeedList from './FeedList';

export default class SearchBar extends Component {
    constructor(props) {
        super(props);
        this.state = {
            results: null,
            url: ''
        }
    }

    onSubmit(e) {
        const { url } = this.state;

        e.preventDefault();

        const response = Meteor.call('getFeed', url, (err, res) => {
            if(!err) {
                this.setState({
                    results:res.entries
                });
                console.log(this.state.results);
            } else {
                console.log(err.reason);
            }
        });
    }

    onChange(e) {
        this.setState({
            url: e.target.value
        });
    }

    render() {
        return (
            <div>
                <form onSubmit={this.onSubmit.bind(this)}>
                    <input type="text" placeholder="Enter a URL" value={this.state.url} onChange={this.onChange.bind(this)}/>
                    <button type="submit">Get Feed</button>
                </form>
                {this.state.results ? <FeedList feedItems={this.state.results}/> : <p>Load a feed</p>}
            </div>
            );
    }
}

【问题讨论】:

  • 一个典型的模式是让一个 cron 作业填充一个发布到客户端并在那里呈现的集合。然后,整个过程可以通过自动更新对用户透明地发生。由于是服务器在执行HTTP.get(),因此客户端集合并不像在其他用例中那样方便。无论如何,我之前发布了一个tuorialt on client side collections,您可能会觉得有用。
  • 我建议使用低级发布 API 使用 setInterval 轮询端点并更新“提要”集合(或任何您想要命名的集合)。 Meteor 指南中有一个基本示例:guide.meteor.com/data-loading.html#custom-publication
  • 这里也是一个更具体的例子,完整的间隔:forums.meteor.com/t/best-way-to-handle-a-3rd-party-endpoint/…
  • 谢谢大家的回复,我去看看!
  • 是否也可以只定义一个客户端集合并将该方法返回的数据存储在该集合中?假设我想保留应用程序的当前结构,只使用方法调用而不是发布

标签: javascript reactjs meteor collections


【解决方案1】:

根本不要在服务器上获取提要。在客户端获取它,并使用定义如下的本地集合保存它:

let localCollection = new Mongo.Collection(null)

关于cmets:

一个典型的模式是让一个 cron 作业填充一个发布到客户端并在那里呈现的集合。

这将被过度设计以满足您的需求,并且通常被认为是典型的错误答案。

【讨论】:

  • 可以做到这一点...但考虑拥有客户端无权访问的 api 调用的凭据(我的情况)。然后它需要在服务器上发生。
猜你喜欢
  • 2015-08-08
  • 2016-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-13
  • 2018-03-06
  • 2015-02-02
相关资源
最近更新 更多