Réagir (Facebook): de l'état à gestion contrôlée des cases à cocher
Je vais avoir un petit problème lors de la tentative de créer une case à cocher qui permet de sélectionner et de désélectionner les autres cases individuelles (sélectionner/désélectionner tout) avec Réagir. J'ai lu http://facebook.github.io/react/docs/forms.html et découvert qu'il existe des différences entre contrôlé et pas contrôlée <input>
s. Mon test de code est comme suit:
var Test = React.createClass({
getInitialState: function() {
return {
data: [
{ id: 1, selected: false },
{ id: 2, selected: false },
{ id: 3, selected: false },
{ id: 4, selected: false }
]
};
},
render: function() {
var checks = this.state.data.map(function(d) {
return (
<div>
<input type="checkbox" data-id={d.id} checked={d.selected} onChange={this.__changeSelection} />
{d.id}
<br />
</div>
);
});
return (
<form>
<input type="checkbox" ref="globalSelector" onChange={this.__changeAllChecks} />Global selector
<br />
{checks}
</form>
);
},
__changeSelection: function(e) {
var id = e.target.getAttribute('data-id');
var state = this.state.data.map(function(d) {
return {
id: d.id,
selected: (d.id === id ? !d.selected : d.selected)
};
});
this.setState({ data: state });
},
__changeAllChecks: function(e) {
var value = this.refs.globalSelector.getDOMNode().checked;
var state = this.state.data.map(function(d) {
return { id: d.id, selected: value };
});
this.setState({ data: state });
}
});
React.renderComponent(<Test />, document.getElementById('content'));
Le "sélecteur Global" fonctionne comme prévu: lorsqu'il est sélectionné, tous les autres contrôles sont sélectionnés. Le problème est que le __changeSelection()
gestionnaire n'est pas déclenché lorsque l'une des autres cases sont cliqués.
Je ne sais pas quelle est la méthode appropriée pour faire ce travail. Peut-être Réagir modèle n'est pas le meilleur pour modéliser ce type d'interaction? Que pouvais-je faire?
Merci d'avance
Vous devez vous connecter pour publier un commentaire.
Dans votre
render
fonction, la portée dethis
pour lachecks
fonction de mappage est différent derender
, qui est le champ d'application vous avez besoin pour__changeSelection
, doncthis.__changeSelection
de ne pas localiser un__changeSelection
de la propriété. Si vous ajoutez un.bind(this)
à la fin de la fonction de mappage, vous pouvez lier son champ d'application pour la mêmethis
commerender
:Sur une note de côté, je voudrais juste passer le
id
à la fonction de gestionnaire au lieu de l'affectation des données-attributs. Cela permettra d'éliminer la nécessité de localiser cet élément dans votre gestionnaire de:Puis mettre à jour votre
__changeSelection
fonction pour passer dans leid
comme le premier arg et supprimer l'attribut de recherche de ligne:Voici un exemple de tout cela mis ensemble, avec un jsfiddle pour vous de l'essayer:
this.__changeSelection(id)
dirais que la fonction immédiatement (par exemple, lors du rendu). Nous voulons juste passer une référence de la fonction de sorte qu'il peut être appelé plus tard par leonChange
événement. Par exemple, si vous tapezconsole.log
dans votre navigateur de la console, il aurait l'impression de sortir de la fonction, mais si vous tapezconsole.log()
il mettrait le feu de la fonction réelle.anyFunc.bind(this, arg)
permettra de créer une nouvelle fonction liée àthis
et ajouter n'importe quel argument(s) passé à la fonction d'origine, mais ne sera pas l'appeler.checked: @props.checkAll
, qui fonctionne comme prévu. Mais, je ne suis pas en mesure de vérifier manuellement/décocher après la définition de cet attribut. Après la suppression de cet attribut, je suis en mesure de le faire manuellementextends Component
syntaxe au lieu decreateClass
Si vous travaillez avec des cases à cocher, vous pouvez utiliser le
checkedLink
attribut. Voici une autre mise en œuvre, qui fait de la case global contrôlé (au lieu de dérive dans le courant de réponses):JsFiddle
Il est plus simple d'utilisation
checkedLink=this.linkState("checkboxValue")
avecLinkedStateMixin
si l'état de muter n'est pas profondément imbriqués (comme c'est le cas dans cette question)Modifier:
checkedLink
etvalueLink
sont désapprouvées, mais ont été recommandées dans les versions précédentes de Réagir.checked: @props.checkAll
, qui fonctionne comme prévu. Mais, je ne suis pas en mesure de vérifier manuellement/décocher après la définition de cet attribut. Après la suppression de cet attribut, je suis en mesure de le faire manuellementcheckedLink
ne semble pas fonctionner du tout. en dépit de la misecheckedLink=true
je ne vois pas la case comme étant vérifié