0

我正在使用 Meteor/React 构建一个社交应用程序。用户通过多对一关系与其他人相关(用户有代表)。

所以我制作了一个成员组件,它返回一个模板,里面有一个表单来选择代表,并创建了一个 API 来对用户执行一些操作。

一切正常,但删除功能不会更新客户端(我用应用程序打开了另一个窗口)。

我觉得我错过了组件概念的重点,那个选择框也应该是一个组件吗?

这是 Member.jsx

import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import { Meteor } from 'meteor/meteor';

import { Members } from '../api/members.js';

// Member component - represents a single member item
export default class Member extends Component {
  componentDidMount() {
    ReactDOM.findDOMNode(this.refs.select_representant).value = this.props.member.representant;
  }

  componentDidUpdate() {
    ReactDOM.findDOMNode(this.refs.select_representant).value = this.props.member.representant;
  }

  setRepresentant() {
    Meteor.call('members.setRepresentant', this.props.member._id, 'oo');
  }

  deleteThisMember() {
    Meteor.call('members.remove', this.props.member._id);
  }

  renderRepresentants() {
    let representants = Members.find().fetch();
    return representants.map((representant) => (
      <option key={representant._id} value={representant._id}>{representant.pseudo}</option>
    ));
  }

  handleSubmit(event) {
    event.preventDefault();

    // Find the text field via the React ref
    const representantId = ReactDOM.findDOMNode(this.refs.select_representant).value.trim();
    const representant = Members.findOne({ _id: representantId });

    Meteor.call('members.setRepresentant', this.props.member._id, representantId);
  }

  render() {
    return (
      <div>

        <h3 className="text">
          {this.props.member.pseudo} <button className="delete" onClick={this.deleteThisMember.bind(this)}>&times;</button>
        </h3>

        <form className="form-horizontal">
          <div className="form-group">
            <label htmlFor="select_representant" className="col-sm-3 control-label">Représentant</label>
            <div className="col-sm-7">
              <select ref="select_representant" className="form-control custom-select" name="select_representant" onChange={this.handleSubmit.bind(this)}>
                {this.renderRepresentants()}
              </select>
            </div>
          </div>
        </form>

      </div>
    );
  }
}

和 members.jsx

import { Mongo } from 'meteor/mongo';
import { Meteor } from 'meteor/meteor';
import { check } from 'meteor/check';

export const Members = new Mongo.Collection('members');

Meteor.methods({
  'members.insert'(pseudo) {
    check(pseudo, String);

    Members.insert({
      pseudo
    });
  },
  'members.remove'(memberId) {
    check(memberId, String);

    Members.remove(memberId);
    represented = Members.find({ representant: memberId }).fetch();
    for(representedItem in represented){
      Members.update(representedItem, { $set: { representant: null } });
    }
  },
  'members.setRepresentant'(memberId, representantId) {
    check(memberId, String);
    check(representantId, String);

    Members.update(memberId, { $set: { representant: representantId } });
  },
});
4

2 回答 2

1

尝试这个:

deleteThisMember() {
  Meteor.call('members.remove', this.props.member._id);
  renderRepresentants();
}

或者,您试图将您的成员列表放在 thie.props 上?

于 2016-11-18T18:28:45.027 回答
1

由于您Members在 React 渲染函数中查询,它不会对数据库中的更改做出反应。您需要使用createContainerfromreact-meteor-data来查看前端的更改:

import { createContainer } from 'meteor/react-meteor-data';
...
export default class Member extends Component {
  ...
  renderRepresentants() {
    let representants = this.props.representants;
    ...
  }
...
}

createContainer(() => {
  return {
    representants: Members.find().fetch()
  };
}, Member);

Members现在,当集合发生变化时,查询应该得到适当的响应式更新。

于 2016-11-18T18:35:58.827 回答