Ich habe Probleme mit Abonnement und Reagieren, vielleicht mache ich es nicht richtig.Meteor/React - Update-Abonnement bei Statuswechsel
Hier ist das Problem: ich möchte eine Seite mit einer Filmliste erstellen, die von einer Mongo-Sammlung zur Verfügung gestellt wird, gibt es auch einen Genre-Filter und eine Schaltfläche "mehr laden".
Wenn ich nur mehr laden, aktualisiere ich die Publikation, um bestehende Artikel zu überspringen und neue zu liefern, funktioniert es gut.
Wenn ich mein Genre Filter ändern, ich meine Publikation einfach mit diesem Filter aktualisieren, funktioniert auch ...
Aber wenn ich, dass zwei Aktionen zusammen zu tun, zum Beispiel: Laden mehr, filtere dann nach Genre, Das Ergebnis sieht schlecht aus und scheint die alten Ergebnisse beizubehalten. Die Seitennumerierung wird nicht auf den Standardwert zurückgesetzt.
Hier ist eine vereinfachte Version meines Codes.
Server-Seite Veröffentlichung:
Meteor.publish('movies.published', function (sort = null, skip = 0, limit = 20, filters = {}) {
if (! sort || typeof sort !== 'object') {
sort = {releaseDate: -1};
}
let params = Object.assign({
webTorrents: {
$exists: true,
$ne: []
},
status: 1,
}, filters);
console.log('----------------Publishing--------------------');
let cursor = Movies.find(params, {
sort: sort,
skip: skip,
limit: limit
});
// Test publication
// Count is always good
console.log(cursor.fetch().length);
return cursor;
});
Client-Seite Komponente:
import React from "react";
import TrackerReact from "meteor/ultimatejs:tracker-react";
import Movies from "/imports/api/movies/movies.js";
import Genres from "/imports/api/genres/genres.js";
const itemPerPage = 1; // let's say 1 item to simplify our test
const defaultOrder = 'releaseDate';
export default class Home extends TrackerReact(React.Component) {
constructor(props) {
super(props);
let options = Object.assign(Meteor.settings.public.list.options, {genres: Genres.find()});
this.state = {
subscription: {
movies: Meteor.subscribe('movies.published', {[defaultOrder]: -1}, 0, itemPerPage),
},
filters: {},
sort: defaultOrder,
options: options,
};
}
componentWillUnmount() {
this.state.subscription.movies.stop();
}
filterByGenre(event) {
let filterGenre = {
['genres.slug']: event.target.value !== '' ? event.target.value : {$ne: null}
};
this.updateFilters(filterGenre);
}
updateFilters(values) {
// Merge filters
let filters = Object.assign(this.state.filters, values);
console.log('updating filters', filters);
// Update subscription with filters values
// here i must reset the pagination
this.state.subscription.movies.stop();
let newSubscription = Object.assign({}, this.state.subscription, {
movies: Meteor.subscribe('movies.published', {[this.state.sort]: -1}, 0, itemPerPage, filters),
});
this.setState({
subscription: newSubscription,
filters: filters,
})
}
loadMore(skip) {
// Add an item
let newSubscription = Object.assign({}, this.state.subscription, {
movies: Meteor.subscribe('movies.published', {[this.state.sort]: -1}, skip, itemPerPage, this.state.filters),
});
this.setState({
subscription: newSubscription,
});
}
render() {
if (! this.state.subscription.movies.ready()) {
return (<div>loading...</div>);
}
// Get our items
let movies = Movies.find().fetch();
return (
<div>
<div className="container-fluid">
{/* Filters */}
<form className="form form-inline">
<div className="form-group m-r m-2x">
<select className="form-control" value={this.state.filters['genres.slug'] && this.state.filters['genres.slug']} onChange={this.filterByGenre.bind(this)}>
<option value="">Genres</option>
{this.state.options.genres.map((genre, key) => {
return <option key={key} value={genre.slug}>{genre.name}</option>
})}
</select>
</div>
</form>
<hr />
{/* list */}
<div className="row list">
{movies.map((movie) => {
return (
<div key={movie._id} className="col-xs-2">{movie.title}</div>
)
})}
</div>
{/* Load more */}
<button id="load-more" type="button" className="btn btn-sm btn-info" onClick={this.loadMore.bind(this, movies.length)}>
Load more
</button>
</div>
<div className="col-xs-3 pull-right text-right">{movies.length} movies</div>
<hr />
</div>
)
}
}
Hier ist ein besserer Weg, das zu tun? Danke für Ihre Hilfe!