获取流星取消订阅数据

Get meteor to unsubscribe from data

由于 meteor 的工作方式,我不确定这是否可行。我正在尝试弄清楚如何取消订阅和订阅集合,并在用户单击按钮时从客户端的 mini mongo 中删除数据。我在下面的示例中遇到的问题是,当用户单击 handleButtonAllCompanies 时,所有数据都会传送到客户端,然后如果他们单击 handleButtonTop100,则不会重新订阅。所以客户端的数据不会改变。可以这样做吗?

路径:CompaniesPage.jsx

export default class CompaniesPage extends Component {
  constructor(props) {
    super(props);

    this.handleButtonAllCompanies = this.handleButtonAllCompanies.bind(this);
    this.handleButtonTop100 = this.handleButtonTop100.bind(this);
  }

  handleButtonAllCompanies(event) {
    event.preventDefault();

    Meteor.subscribe('companiesAll');
  }

  handleButtonTop100(event) {
    event.preventDefault();

    Meteor.subscribe('companiesTop100');
  }

  render() {
    // console.log(1, this.props.companiesASX);
    return (
      <div>
        <Button color="primary" onClick={this.handleButtonAllCompanies}>All</Button>
        <Button color="primary" onClick={this.handleButtonTop100}>Top 100</Button>
      </div>
    );
  }
}

路径:Publish.js

Meteor.publish('admin.handleButtonAllCompanies', function() {
  return CompaniesASX.find({});
});

Meteor.publish('admin.handleButtonTop100', function() {
  return CompaniesASX.find({}, { limit: 100});
});

这绝对是可能的,但方法是修复您的出版物。您想考虑 MVC,即尽可能将数据和模式与您要呈现它的方式分开。这意味着您不应出于两个特定目的维护同一集合的两个出版物。相反,您想重复使用相同的出版物,但只需根据需要更改参数即可。

Meteor.publish('companies', function(limit) {
  if (limit) {
    return CompaniesASX.find({}, { limit });
  } else { 
    return CompaniesASX.find({});
  }
});

然后您可以将按钮处理程序定义为:

  handleButtonAllCompanies(event) {
    event.preventDefault();
    Meteor.subscribe('companies');
  }

  handleButtonTop100(event) {
    event.preventDefault();
    Meteor.subscribe('companies', 100);
  }

这样您是在更改现有订阅,而不是创建新订阅。

我还不是很熟悉 meteor 中的 React。但在大火中你甚至不需要 re-subscribe。您只需提供一个反应变量作为订阅参数,只要它发生变化,流星就会反应地更新订阅。反应可能也是如此,但我不确定如何。

好的,首先要感谢@Christian Fritz,他的建议让我走上了正轨。我希望这可以帮助别人。

我没有意识到订阅应该在容器组件中进行控制,而不是在页面组件中。通过使用 Session.setSession.get 我能够更新 Container 组件来更新订阅。

这有效(如果有更好或更多的流星方式,请post),我希望这对遇到类似问题的其他人有所帮助。

路径CompaniesContainer.js

export default UploadCSVFileContainer = withTracker(({ match }) => {
  const limit = Session.get('limit');

  const companiesHandle = Meteor.subscribe('companies', limit);
  const companiesLoading = !companiesHandle.ready();
  const companies = Companies.find().fetch();
  const companiesExists = !companiesLoading && !!companies;

  return {
    companiesLoading,
    companies,
    companiesExists,
    showCompanies: companiesExists ? Companies.find().fetch() : []
  };
})(UploadCSVFilePage);

路径:CompaniesPage.jsx

export default class CompaniesPage extends Component {
  constructor(props) {
    super(props);

    this.handleButtonAllCompanies = this.handleButtonAllCompanies.bind(this);
    this.handleButtonTop100 = this.handleButtonTop100.bind(this);
  }

  handleButtonAllCompanies(event) {
    event.preventDefault();
    // mongodb limit value of 0 is equivalent to setting no limit
    Session.set('limit', 0)
  }

  handleButtonTop100(event) {
    event.preventDefault();
    Session.set('limit', 100)
  }

  render() {
    return (
      <div>
        <Button color="primary" onClick={this.handleButtonAllCompanies}>All</Button>
        <Button color="primary" onClick={this.handleButtonTop100}>Top 100</Button>
      </div>
    );
  }
}

路径:Publish.js

Meteor.publish('companies', function() {
  if (limit || limit === 0) {
    return Companies.find({}, { limit: limit });
  }
});

路径CompaniesContainer.js

export default CompaniesContainer = withTracker(() => {
  let companiesHandle;  // or fire subscribe here if you want the data to be loaded initially
  const getCompanies = (limit) => {
    companiesHandle = Meteor.subscribe('companies', limit);
  }

  return {
    getCompanies,
    companiesLoading: !companiesHandle.ready(),
    companies: Companies.find().fetch(),
  };
})(CompaniesPage);

路径:CompaniesPage.jsx

export default class CompaniesPage extends Component {
  constructor(props) {
    super(props);
    this.handleButtonAllCompanies = this.handleButtonAllCompanies.bind(this);
    this.handleButtonTop100 = this.handleButtonTop100.bind(this);
  }

  getCompanies(limit) {
    this.props.getCompanies(limit);
  }

  handleButtonAllCompanies(event) {
    event.preventDefault();
    // mongodb limit value of 0 is equivalent to setting no limit
    this.getCompanies(0);
  }

  handleButtonTop100(event) {
    event.preventDefault();
    this.getCompanies(100);
  }

  render() {
    return (
      <div>
        <Button color="primary" onClick={this.handleButtonAllCompanies}>All</Button>
        <Button color="primary" onClick={this.handleButtonTop100}>Top 100</Button>
      </div>
    );
  }
}

路径:Publish.js

Meteor.publish('companies', function(limit) {
  if (!limit) { limit = 0; }
  return Companies.find({}, { limit: limit });
});