Je crée un constructeur de règle semblable à celui-ci:GWT emboîtées Rédacteurs - rinçage Pas du cycle correctement ou donnant détecté une erreur
Il peut y avoir deux types d'objets de règle:
- JoinMetadataCondition: contient le type de jointure ("et" ou "ou") et une liste d'autres conditions de métadonnées à joindre
- LeafMet adataCondition: il contient une définition de règle (variable, opérateur, valeur)
Ces deux conditions mettre en œuvre une MetadataCondition l'interface.
Approche 1
J'ai utilisé trois différents éditeurs pour tenter de modifier les règles, mais je me fais un cycle erreur détectée qui est logique que les règles sont récursives. Voici les trois éditeurs.
MetadataConditionEditor
Il utilise le AbstractSubTypeEditor décrit here et here
C'est le point d'entrée dans les éditeurs de règles. Il recevra la condition de métadonnées de niveau supérieur et, à partir de là, il attachera l'éditeur approprié.
public class MetadataConditionEditor extends Composite implements Editor<MetadataCondition> {
interface Binder extends UiBinder<Widget, MetadataConditionEditor> {}
@Ignore
final JoinMetadataConditionEditor joinMetadataEditor = LibsFactory.injector().getJoinMetadataConditionEditor();
@Path("")
final AbstractSubTypeEditor<MetadataCondition, JoinMetadataCondition, JoinMetadataConditionEditor> joinMetadataEditorWrapper =
new AbstractSubTypeEditor<MetadataCondition, JoinMetadataCondition, JoinMetadataConditionEditor>(joinMetadataEditor) {
@Override
public void setValue(final MetadataCondition value)
{
setValue(value, isJoinMetadataCondition(value));
if(isJoinMetadataCondition(value)) {
container.clear();
container.add(joinMetadataEditor);
}
}
};
@Ignore
final LeafMetadataConditionEditor leafMetadataEditor = LibsFactory.injector().getLeafMetadataConditionEditor();
@Path("")
final AbstractSubTypeEditor<MetadataCondition, LeafMetadataCondition, LeafMetadataConditionEditor> leafMetadataEditorWrapper =
new AbstractSubTypeEditor<MetadataCondition, LeafMetadataCondition, LeafMetadataConditionEditor>(leafMetadataEditor) {
@Override
public void setValue(final MetadataCondition value)
{
setValue(value, !isJoinMetadataCondition(value));
if(!isJoinMetadataCondition(value)) {
container.clear();
container.add(leafMetadataEditor);
}
}
};
@UiField @Ignore SimplePanel container;
public MetadataConditionEditor() {
initWidget(GWT.<Binder> create(Binder.class).createAndBindUi(this));
}
private Boolean isJoinMetadataCondition(MetadataCondition value) {
return value instanceof JoinMetadataCondition;
}}
JoinMetadataConditionEditor
Utilisé pour éditer les objets JoinMetadataCondition
JoinMetadataConditionEditor public class étend Composite Editor {implémente l'interface Binder étend UiBinder {}
@UiField @Ignore FlowPanel container;
@UiField
@Path("type")
ManualSelectEditor type;
@Path("conditions")
ListEditor<MetadataCondition, MetadataConditionEditor> conditions;
public JoinMetadataConditionEditor() {
initWidget(GWT.<Binder> create(Binder.class).createAndBindUi(this));
conditions = ListEditor.of(new MetadataEditorSource());
type.setSelectOptions(EditorConstants.metadataJoins);
}
private class MetadataEditorSource extends EditorSource<MetadataConditionEditor>
{
@Override
public MetadataConditionEditor create(int index)
{
final MetadataConditionEditor subEditor = new MetadataConditionEditor();
container.insert(subEditor, index);
return subEditor;
}
public void dispose(MetadataConditionEditor subEditor) {
container.remove(subEditor);
}
}}
LeafM etadataConditionEditor
Enfin l'éditeur utilisé pour la LeafMetadataCondition
public class LeafMetadataConditionEditor extends Composite implements Editor<LeafMetadataCondition> {
interface Binder extends UiBinder<Widget, LeafMetadataConditionEditor> {}
@UiField TextBoxEditor name;
@UiField TextBoxEditor value;
@UiField ManualSelectEditor operator;
public LeafMetadataConditionEditor() {
initWidget(GWT.<Binder> create(Binder.class).createAndBindUi(this));
operator.setSelectOptions(EditorConstants.metadataOperators);
}
}
Question
La question est: Comment puis-je éviter le cycle détecté une erreur ou construire cette récursivité d'une manière qui fonctionne ?
Note: Je suis ouvert à de nouvelles façons de le faire. J'ai essayé quelques autres routes telles qu'initialiser des pilotes pour chaque sous-éditeur et les rendre tous CompositeEditors. Cela a été compilé et chargé, mais au moment de vider les pilotes, les valeurs du sous-éditeur n'étaient pas correctement construites, même si les méthodes flush() semblaient être appelées, mais les éditeurs parents ne les utilisaient pas.
Approche 2
La seconde approche consiste à utiliser un CompositeEditor et ayant les éditeurs sous créer leurs propres pilotes qui sont ensuite rincée pour créer le résultat final.
MetadataConditionEditor
public class MetadataConditionEditor extends Composite implements
CompositeEditor<MetadataCondition, MetadataCondition, SimpleDriverEditor<MetadataCondition>>,
LeafValueEditor<MetadataCondition>
{
interface Binder extends UiBinder<Widget, MetadataConditionEditor> {}
// private SimpleBeanEditorDriver<MetadataCondition, ? extends Editor<MetadataCondition>> subDriver;
private EditorChain<MetadataCondition, SimpleDriverEditor<MetadataCondition>> chain;
private SimpleDriverEditor<MetadataCondition> subEditor;
private EditorDelegate<MetadataCondition> delegate;
private MetadataCondition value;
@UiField @Ignore SimplePanel container;
public MetadataConditionEditor() {
initWidget(GWT.<Binder> create(Binder.class).createAndBindUi(this));
}
@Override
public void flush()
{
if(Utils.isNull(subEditor))
return;
GWT.log("----- flush-pre - " + System.identityHashCode(this) + " - " + value);// TODO
value = subEditor.flush();
GWT.log("----- flush-post-1 - " + System.identityHashCode(this) + " - " + value.toJson());// TODO
}
@Override
public void onPropertyChange(String... paths) {}
@Override
@SuppressWarnings("unchecked")
public void setValue(MetadataCondition value)
{
this.value = value;
// subDriver = null;
if(Utils.isNull(value))
return;
GWT.log("----- setValue - " + value);// TODO
if(value instanceof JoinMetadataCondition) {
SimpleDriverEditor<JoinMetadataCondition> newSubEditor = LibsFactory.injector().getJoinMetadataConditionEditor();
SimpleDriverEditor<? extends MetadataCondition> newSubEditor1 = newSubEditor;
subEditor = (SimpleDriverEditor<MetadataCondition>) newSubEditor1;
newSubEditor.edit((JoinMetadataCondition) value);
}
container.clear();
container.add(subEditor);
}
@Override
public void setDelegate(EditorDelegate<MetadataCondition> delegate) {
GWT.log("----- setDelegate - " + delegate);// TODO
this.delegate = delegate;
}
@Override
public MetadataCondition getValue() {
GWT.log("----- getValue - " + System.identityHashCode(this) + " - " + value);// TODO
return value;
}
@Override
public SimpleDriverEditor<MetadataCondition> createEditorForTraversal() {
GWT.log("----- createEditorForTraversal - " + subEditor);// TODO
return subEditor;
}
@Override
public String getPathElement(SimpleDriverEditor<MetadataCondition> subEditor) {
GWT.log("----- getPathElement - " + delegate.getPath());// TODO
return delegate.getPath();
}
@Override
public void setEditorChain(EditorChain<MetadataCondition, SimpleDriverEditor<MetadataCondition>> chain) {
GWT.log("----- setEditorChain - " + chain);// TODO
this.chain = chain;
}
}
JoinMetadataConditionEditor
public class JoinMetadataConditionEditor extends Composite implements SimpleDriverEditor<JoinMetadataCondition>
{
interface Binder extends UiBinder<Widget, JoinMetadataConditionEditor> {}
interface Driver extends SimpleBeanEditorDriver<JoinMetadataCondition, JoinMetadataConditionEditor> {}
private Driver driver = GWT.create(Driver.class);
@Inject
ModelFactory factory;
@UiField @Ignore HTML label;
@UiField @Ignore FlowPanel container;
@UiField @Ignore Button deleteMetadata;
@UiField
@Path("type")
ManualSelectEditor type;
@Path("conditions")
ListEditor<MetadataCondition, MetadataConditionEditor> conditions = ListEditor.of(new MetadataEditorSource());
public JoinMetadataConditionEditor() {
initWidget(GWT.<Binder> create(Binder.class).createAndBindUi(this));
type.setSelectOptions(EditorConstants.metadataJoins);
}
public SimpleBeanEditorDriver<JoinMetadataCondition, JoinMetadataConditionEditor> createDriver() {
driver.initialize(this);
return driver;
}
@Override
public JoinMetadataCondition flush()
{
GWT.log("---------- flush-pre - " + System.identityHashCode(this) + " - " + type.getValue());// TODO
GWT.log("---------- flush-pre - " + System.identityHashCode(this) + " - " + conditions.getList());// TODO
JoinMetadataCondition value = driver.flush();
GWT.log("---------- flush-post - " + System.identityHashCode(this) + " - " + value.toJson());// TODO
return value;
}
@Override
public void edit(JoinMetadataCondition object) {
createDriver();
driver.edit(object);
label.setText(getLabel(object));
}
private String getLabel(JoinMetadataCondition value) {
if(StringUtils.equals(value.getType(), JoinMetadataTypes.AND.value()))
return LibsFactory.lang().allConditionsAreTrue();
return LibsFactory.lang().anyConditionsAreTrue();
}
@Override
public HandlerRegistration addDeleteHandler(MetadataDeletedHandler handler) {
return addHandler(handler, MetadataDeletedEvent.TYPE);
}
@UiHandler("deleteMetadata")
protected void onDeleteMetadata(ClickEvent event) {
fireEvent(new MetadataDeletedEvent((Event) event.getNativeEvent()));
}
@UiHandler("addAllMetadata")
protected void onAddAllMetadata(ClickEvent event) {
add(factory.newJoinMetadataCondition(JoinMetadataTypes.AND));
}
@UiHandler("addOrMetadata")
protected void onAddOrMetadata(ClickEvent event) {
add(factory.newJoinMetadataCondition(JoinMetadataTypes.OR));
}
@UiHandler("addLeafMetadata")
protected void onAddLeafMetadata(ClickEvent event) {
add(factory.newLeafMetadataCondition());
}
private void add(MetadataCondition metadata) {
try {
GWT.log("--------------------------------- add() - pre");// TODO
conditions.getList().add(metadata);
clearErrors();
} catch (Exception e) {
GWT.log("--------------------------------- add() - " + e.getMessage()); // TODO
}
}
public void clearErrors() {
type.getErrorHandler().clearErrors();
}
private class MetadataEditorSource extends EditorSource<MetadataConditionEditor>
{
@Override
public MetadataConditionEditor create(int index)
{
final MetadataConditionEditor subEditor = new MetadataConditionEditor();
container.insert(subEditor, index);
return subEditor;
}
public void dispose(MetadataConditionEditor subEditor) {
container.remove(subEditor);
}
}
}
Problème
Cette deuxième approche semble presque travailler. Le problème est que lorsque je vide le pilote, les sous-pilotes sont également vidés, mais pour une raison quelconque, les éditeurs parents n'incluent pas réellement les valeurs des sous-éditeurs.
Les états de journal générer au-dessus de la sortie suivante lorsque j'ai une condition d'inscription unique imbriqué:
----- flush-pre - 111 - [email protected]
---------- flush-pre - 761 - null
---------- flush-pre - 761 - [[email protected]]
----- flush-pre - 886 - [email protected]
---------- flush-pre - 929 - and
---------- flush-pre - 929 - []
---------- flush-post - 929 - {"type":"and", "conditions":[]}
----- flush-post-1 - 886 - {"type":"and", "conditions":[]}
----- getValue - 886 - [email protected]
---------- flush-post - 761 - {"type":"and", "conditions":[]}
----- flush-post-1 - 111 - {"type":"and", "conditions":[]}
----- getValue - 111 - [email protected]
{"type":"and", "conditions":[]}
Comme vous pouvez le voir l'éditeur principal (111) ne comprend pas réellement le contenu de celui-ci est subeditors. Des idées pour lesquelles cela pourrait être?
Avez-vous obtenu n'importe où avec ceci? C'est assez ambitieux! (nice;)) – slugmandrew
Je l'ai fait en fait, mais j'ai essentiellement dû rouler mon propre LeafValueEditor et construire le formulaire à la main :-) –