Search in sources :

Example 1 with MapProperty

use of com.vaadin.client.flow.nodefeature.MapProperty in project flow by vaadin.

the class GwtTemplateBinderTest method createNgForModelNode.

/**
 * Creates 3 children for the {@code parent}: the first one is defined via
 * the {@code firstChildTag}, the second is defined via the {@code ngForTag}
 * (this is the template which represents *ngFor) and the
 * {@code lastChildTag} defines the third child.
 * <p>
 * {@code collectionVar} is an outer scope collection variable name and
 * {@code textVar} is text template parameter name. It's used inside *ngFor
 * template.
 * <p>
 * So the result is:
 *
 * <pre>
 *                                 parent
 *                                   |
 *              ________________________________________________________
 *              |                          |                           |
 *      <firstChildTag>    <ngForTag>{{textVar}}</ngForTag>     <lastChildTag>
 * </pre>
 */
private StateNode createNgForModelNode(TestElementTemplateNode parent, String firstChildTag, String ngForTag, String lastChildTag, String collectionVar, String textVar) {
    TestElementTemplateNode child1 = TestElementTemplateNode.create(firstChildTag);
    int child1Id = 57;
    registry.getTemplateRegistry().register(child1Id, child1);
    TestForTemplateNode templateNode = TestTemplateNode.create(ForTemplateNode.TYPE);
    int templateId = 42;
    registry.getTemplateRegistry().register(templateId, templateNode);
    TestElementTemplateNode forChild = TestElementTemplateNode.create(ngForTag);
    templateNode.setCollectionVariable(collectionVar);
    TestTextTemplate text = TestTextTemplate.create(TestBinding.createTextValueBinding(textVar));
    int textChildId = 85;
    registry.getTemplateRegistry().register(textChildId, text);
    forChild.setChildrenIds(new double[] { textChildId });
    int forChildId = 11;
    registry.getTemplateRegistry().register(forChildId, forChild);
    templateNode.setChildrenIds(new double[] { forChildId });
    TestElementTemplateNode child2 = TestElementTemplateNode.create(lastChildTag);
    int child2Id = 84;
    registry.getTemplateRegistry().register(child2Id, child2);
    parent.setChildrenIds(new double[] { child1Id, templateId, child2Id });
    NodeMap model = stateNode.getMap(NodeFeatures.TEMPLATE_MODELMAP);
    MapProperty property = model.getProperty(collectionVar);
    StateNode modelNode = new StateNode(1, tree);
    property.setValue(modelNode);
    return modelNode;
}
Also used : MapProperty(com.vaadin.client.flow.nodefeature.MapProperty) StateNode(com.vaadin.client.flow.StateNode) NodeMap(com.vaadin.client.flow.nodefeature.NodeMap)

Example 2 with MapProperty

use of com.vaadin.client.flow.nodefeature.MapProperty in project flow by vaadin.

the class GwtTemplateBinderTest method testNgFor_updateModel.

public void testNgFor_updateModel() {
    TestElementTemplateNode parent = TestElementTemplateNode.create("div");
    String textVar = "text";
    String collectionVar = "items";
    // create 3 children for the parent: <div/><li
    // *ngFor>{{text}}</li><span/>
    StateNode modelNode = createNgForModelNode(parent, "div", "li", "span", collectionVar, textVar);
    StateNode varNode = new StateNode(2, tree);
    varNode.getMap(NodeFeatures.TEMPLATE_MODELMAP).getProperty(textVar).setValue("foo");
    modelNode.getList(NodeFeatures.TEMPLATE_MODELLIST).add(0, varNode);
    Element element = createElement(parent);
    Reactive.flush();
    NodeMap model = stateNode.getMap(NodeFeatures.TEMPLATE_MODELMAP);
    MapProperty property = model.getProperty(collectionVar);
    modelNode = new StateNode(3, tree);
    property.setValue(modelNode);
    varNode = new StateNode(4, tree);
    varNode.getMap(NodeFeatures.TEMPLATE_MODELMAP).getProperty(textVar).setValue("bar");
    modelNode.getList(NodeFeatures.TEMPLATE_MODELLIST).add(0, varNode);
    Reactive.flush();
    assertEquals("DIV", element.getTagName());
    NodeList childNodes = element.getChildNodes();
    assertTrue(childNodes.getLength() > 1);
    assertEquals("DIV", ((Element) childNodes.item(0)).getTagName());
    assertEquals("SPAN", ((Element) childNodes.item(childNodes.getLength() - 1)).getTagName());
    Element li = ((Element) childNodes.item(childNodes.getLength() - 2));
    assertEquals("LI", li.getTagName());
    assertEquals(4, childNodes.getLength());
    // comment
    assertEquals(Node.COMMENT_NODE, childNodes.item(1).getNodeType());
    assertEquals("bar", li.getTextContent());
}
Also used : Element(elemental.dom.Element) MapProperty(com.vaadin.client.flow.nodefeature.MapProperty) NodeList(elemental.dom.NodeList) StateNode(com.vaadin.client.flow.StateNode) NodeMap(com.vaadin.client.flow.nodefeature.NodeMap)

Example 3 with MapProperty

use of com.vaadin.client.flow.nodefeature.MapProperty in project flow by vaadin.

the class PolymerUtils method convertToJson.

/**
 * Makes an attempt to convert an object into json.
 *
 * @param object
 *            the object to convert to json
 * @return json from object, {@code null} for null
 */
public static JsonValue convertToJson(Object object) {
    if (object instanceof StateNode) {
        StateNode node = (StateNode) object;
        NodeFeature feature = null;
        if (node.hasFeature(NodeFeatures.ELEMENT_PROPERTIES)) {
            feature = node.getMap(NodeFeatures.ELEMENT_PROPERTIES);
        } else if (node.hasFeature(NodeFeatures.TEMPLATE_MODELLIST)) {
            feature = node.getList(NodeFeatures.TEMPLATE_MODELLIST);
        } else if (node.hasFeature(NodeFeatures.BASIC_TYPE_VALUE)) {
            return convertToJson(node.getMap(NodeFeatures.BASIC_TYPE_VALUE).getProperty(NodeProperties.VALUE));
        }
        assert feature != null : "Don't know how to convert node without map or list features";
        JsonValue convert = feature.convert(PolymerUtils::convertToJson);
        if (convert instanceof JsonObject && !((JsonObject) convert).hasKey("nodeId")) {
            ((JsonObject) convert).put("nodeId", node.getId());
        }
        return convert;
    } else if (object instanceof MapProperty) {
        MapProperty property = (MapProperty) object;
        if (property.getMap().getId() == NodeFeatures.BASIC_TYPE_VALUE) {
            return convertToJson(property.getValue());
        } else {
            JsonObject convertedObject = Json.createObject();
            convertedObject.put(property.getName(), convertToJson(property.getValue()));
            return convertedObject;
        }
    } else {
        return WidgetUtil.crazyJsoCast(object);
    }
}
Also used : NodeFeature(com.vaadin.client.flow.nodefeature.NodeFeature) MapProperty(com.vaadin.client.flow.nodefeature.MapProperty) StateNode(com.vaadin.client.flow.StateNode) JsonValue(elemental.json.JsonValue) JsonObject(elemental.json.JsonObject)

Example 4 with MapProperty

use of com.vaadin.client.flow.nodefeature.MapProperty in project flow by vaadin.

the class ElementTemplateBindingStrategy method bind.

@Override
protected void bind(StateNode modelNode, Element element, int templateId, TemplateBinderContext context) {
    ElementTemplateNode templateNode = (ElementTemplateNode) getTemplateNode(modelNode.getTree(), templateId);
    bindProperties(modelNode, templateNode, element);
    bindClassNames(modelNode, templateNode, element);
    bindAttributes(modelNode, templateNode, element);
    JsArray<Double> children = templateNode.getChildrenIds();
    if (children != null) {
        for (int i = 0; i < children.length(); i++) {
            int childTemplateId = children.get(i).intValue();
            Node child = createAndBind(modelNode, childTemplateId, context);
            DomApi.wrap(element).appendChild(child);
        }
    }
    registerEventHandlers(context.getTemplateRoot(), templateNode, element);
    MapProperty overrideProperty = modelNode.getMap(NodeFeatures.TEMPLATE_OVERRIDES).getProperty(String.valueOf(templateNode.getId()));
    if (overrideProperty.hasValue()) {
        /*
             * Bind right away. We don't need to listen to property value
             * changes since the value will never change once it has been set.
             */
        bindOverrideNode(element, overrideProperty, context);
    } else {
        /*
             * React in case an override nodes appears later on.
             */
        EventRemover remover = overrideProperty.addChangeListener(e -> Reactive.addFlushListener(() -> bindOverrideNode(element, overrideProperty, context)));
        /*
             * Should preferably remove the change listener immediately when the
             * first event is fired, but Java makes it so difficult to reference
             * the remover from inside the event handler.
             */
        modelNode.addUnregisterListener(e -> remover.remove());
    }
    if (element == context.getTemplateRoot().getDomNode()) {
        // Only bind element.$server for the template root element using the
        // data in the state node. Other elements might get their own
        // $server through an override node
        ServerEventHandlerBinder.bindServerEventHandlerNames(element, context.getTemplateRoot());
    }
}
Also used : EventRemover(elemental.events.EventRemover) StateNode(com.vaadin.client.flow.StateNode) Node(elemental.dom.Node) MapProperty(com.vaadin.client.flow.nodefeature.MapProperty)

Example 5 with MapProperty

use of com.vaadin.client.flow.nodefeature.MapProperty in project flow by vaadin.

the class InitialPropertiesHandlerTest method flushPropertyUpdates_updateIsNotInProgress_flushForEechProperty.

@Test
public void flushPropertyUpdates_updateIsNotInProgress_flushForEechProperty() {
    Mockito.when(tree.isUpdateInProgress()).thenReturn(false);
    StateNode node = new StateNode(1, tree);
    NodeMap properties = node.getMap(NodeFeatures.ELEMENT_PROPERTIES);
    MapProperty property1 = properties.getProperty("foo");
    property1.setValue("bar");
    MapProperty property2 = properties.getProperty("other");
    property2.setValue("value");
    handler.nodeRegistered(node);
    Mockito.when(tree.getNode(node.getId())).thenReturn(node);
    handler.flushPropertyUpdates();
    property1.setValue("baz");
    property2.setValue("foo");
    handler.handlePropertyUpdate(property1);
    handler.handlePropertyUpdate(property2);
    AtomicInteger count = new AtomicInteger();
    FlushListener listener = () -> count.incrementAndGet();
    property1.addChangeListener(event -> Reactive.addFlushListener(listener));
    property2.addChangeListener(event -> Reactive.addFlushListener(listener));
    Reactive.flush();
    Assert.assertEquals(2, count.get());
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) FlushListener(com.vaadin.client.flow.reactive.FlushListener) MapProperty(com.vaadin.client.flow.nodefeature.MapProperty) StateNode(com.vaadin.client.flow.StateNode) NodeMap(com.vaadin.client.flow.nodefeature.NodeMap) Test(org.junit.Test)

Aggregations

MapProperty (com.vaadin.client.flow.nodefeature.MapProperty)40 NodeMap (com.vaadin.client.flow.nodefeature.NodeMap)18 StateNode (com.vaadin.client.flow.StateNode)12 Test (org.junit.Test)8 Element (elemental.dom.Element)7 JsonObject (elemental.json.JsonObject)6 UpdatableModelProperties (com.vaadin.client.flow.model.UpdatableModelProperties)5 JsonValue (elemental.json.JsonValue)3 NodeFeature (com.vaadin.client.flow.nodefeature.NodeFeature)2 SchedulerImpl (com.google.gwt.core.client.impl.SchedulerImpl)1 Computation (com.vaadin.client.flow.reactive.Computation)1 FlushListener (com.vaadin.client.flow.reactive.FlushListener)1 Node (elemental.dom.Node)1 NodeList (elemental.dom.NodeList)1 Text (elemental.dom.Text)1 EventRemover (elemental.events.EventRemover)1 MouseEvent (elemental.events.MouseEvent)1 JsonArray (elemental.json.JsonArray)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1