Titanium JIRA Archive
Alloy (ALOY)

[ALOY-1282] Ti.Map.View > Annotation data-binding not working as expected

GitHub Issuen/a
TypeBug
PriorityNone
StatusOpen
ResolutionUnresolved
Affected Version/sAlloy 1.6.2
Fix Version/sn/a
ComponentsModels, XML
Labelsn/a
ReporterFokke Zandbergen
AssigneeBruce Wayne
Created2015-06-25T08:03:01.000+0000
Updated2015-06-26T08:05:32.000+0000

Description

The way Map/Annotations data-binding is implemented for ALOY-503 is not working as can be expected from how other data-binding works on other view elements.

The only way it works

It only works if you use the <Module> tag and no repeater object. The model attributes must be identical to the property names of the Ti.Map.Annotation object because the generated data-binding will use createAnnotation(model.toJSON()), or you need to use dataTransform.
<Module module="ti.map" method="createView" dataCollection="pin" />

dataTransform is used exclusive, with no fallback on model

For other views, when you use dataTransform it will fall back to the model attributes when the transformation does not include the required property. This means the transform function only needs to return the fields that have been transformed. Instead, for the Map/Annotations data-binding is relies solely on the returned transformation, with no fallback:
        for (var i = 0; len > i; i++) {
            var __alloyId3 = models[i];
            __alloyId2.push(require("ti.map").createAnnotation(transformLocation(__alloyId3)));
        }
        $.__views.__alloyId1.annotations = __alloyId2;

Repeater objects are not supported

You'd expect to be able/required to use a repeater object, allowing you to map any attribute to any property and set styles via TSS.
<Module module="ti.map" method="createView" dataCollection="pin">
  <Annotation title="{address}" latitude="{lat}" longitude="{lng}" />
</Module>
Instead, any annotations in the <Module> tag will be created as is, resulting in code which is likely to crash your app like:
    $.__views.__alloyId2 = require("ti.map").createAnnotation({
        latitude: 0/0,
        longitude: 0/0,
        title: "undefined" != typeof $model.__transform["address"] ? $model.__transform["address"] : $model.get("address"),
        id: "__alloyId2"
    });

Regular view tag is not supported

You'd expect to be able to use the much nicer <View> tag, but when you do Alloy won't recognise it as a ti.map object, which is strange since the module attribute still says so.
<View module="ti.map" dataCollection="pin" />
Instead, the loop in the collection event listener is empty:
        for (var i = 0; len > i; i++) {
            var __alloyId3 = models[i];
            __alloyId3.__transform = {};

            // NOTHING HERE

        }

Comments

  1. Fokke Zandbergen 2015-06-26

    For repeater objects, I assume the/a reason this wasn't used is that you can also add other types of children views to the map as overlays. Still, in that case we should do something like:
       <View module="ti.map">
         <Annotations dataCollection="pin">
           <Annotation title="{address}" latitude="{lat}" longitude="{lng}" />
         </Annotations>
         <Button>Some button</Button>
       </View>
       
    That way, you could maybe even bind multiple collections to the same map.

JSON Source