Titanium JIRA Archive
Alloy (ALOY)

[ALOY-1478] Data binding fails when binding string or model attribute name has dash, space or quote

GitHub Issuen/a
TypeBug
PriorityHigh
StatusClosed
ResolutionFixed
Resolution Date2016-08-04T00:22:20.000+0000
Affected Version/salloy 1.7.35, alloy 1.8.0
Fix Version/sRelease 5.4.0, alloy 1.9.0
ComponentsModels, XML
Labelsn/a
ReporterFokke Zandbergen
AssigneeFeon Sua Xin Miao
Created2016-03-29T12:25:26.000+0000
Updated2016-08-04T17:04:38.000+0000

Description

Alloy data binding can't handle complex bindings strings or model attributes names that contain a dash, space or quotes. This is in part because of the way it renders the compiled \_.template() code, but also because of limitations in \_.template() itself: http://stackoverflow.com/a/15956433/4626813
<Alloy>
	<Model src="mymodel" />
	<Collection src="mymodel" />
	<Window>
		<ScrollView layout="vertical">

			<!-- ALL OK -->
			<Label top="30" text="{mymodel.a}" />

			<!-- COMPILE ERROR -->
			<!-- <Label text="{mymodel.a'b}" /> -->
			<!-- <Label text="he's {mymodel.a}" /> -->

			<!-- RUN-TIME ERROR -->
			<!-- <Label text="{mymodel.a-b}" /> -->
			<!-- <Label text="{mymodel[a-b]}" /> -->
			<!-- <Label text="{mymodel.a b}" /> -->
			<!-- <Label text='{mymodel.a"b}' /> -->

			<ListView>
				<ListSection dataCollection="mymodel">

					<!-- ALL OK -->
					<ListItem title="{a}" />

					<!-- COMPILE ERROR -->
					<!-- <ListItem title="{a'b}" /> -->

					<!-- RUN-TIME ERROR -->
					<!-- <ListItem title="{a-b}" /> -->
					<!-- <ListItem title="{[a-b]}" /> -->
					<!-- <ListItem title="{a b}" /> -->
					<!-- <ListItem title='{a"b}' /> -->

				</ListSection>
			</ListView>
		</ScrollView>
	</Window>
</Alloy>
*index.js*
var test = {
  a: 'a',
  'a-b': 'a-b',
  'a b': 'a b',
  'a"b': 'a"b',
  "a'b": "a'b"
};

Alloy.Models.mymodel.set(test);
Alloy.Collections.mymodel.reset([test]);

$.index.open();
*mymodel.js*
exports.definition = {};

Comments

  1. Fokke Zandbergen 2016-03-31

    Wil be done as part of ALOY-1480
  2. Fokke Zandbergen 2016-03-31

    Combined PR for ALOY-1478, ALOY-1480, ALOY-1481 and ALOY-1482: https://github.com/appcelerator/alloy/pull/780
  3. Feon Sua Xin Miao 2016-04-24

    PR merged.
  4. Eric Wieber 2016-08-02

    Reopening as I am unable to use model attributes with dashes, spaces, or quotes in the name when using a collection via the dataCollection property. Tested using: MacOS 10.11.5 (15F31a) Ti SDK 5.4.0.v20160801022303 Appc NPM 4.2.7 Appc CLI 5.4.0-37 Alloy 1.9.1 Xcode 7.3.1 (7D1014) In the provided code, using a model with dashes, spaces, or quotes in the name is working (simply uncomment the Labels in the scrollview, but outside the listview). However trying to use the dataCollection property and referencing the attributes with spaces, dashes, or quotes in the name will not compile. You can see this by uncommenting the ListItems in the ListSection of the provided code or by using the below example project: (You can make the below project compile by changing the 'dash-dash' and 'space space' attributes in the xml to the 'greeting' and 'subject' attributes) *index.xml*
       <Alloy>
       	<Model src="model-a" />
       	<Model src="modelb" />
       	<Collection src="model-a" />
       	<Window backgroundColor="white" layout="vertical">
       		<Label top="20" font="{['model-a'].font}" text="{['model-a'].greeting} {modelb['mix it']}" />
       		<Label font="{['model-a'].font}" text="well {['model-a'].greeting}" />
       		<Label font="{['model-a'].font}" text="{['model-a'].greeting} {modelb.deep.link}!" />
       		<Label font="{['model-a'].font}" text="well {['model-a'].greeting} there's {['model-a'].subject}!" />
       		<ListView height="Ti.UI.SIZE" canScroll="false">
       			<ListSection dataCollection="model-a">
       				<ListItem font="{font}" title="well {dash-dash} there {space space}!" />
       			</ListSection>
       		</ListView>
       	</Window>
       </Alloy>
       
    *index.js*
       var attributes = {
         greeting: 'hello',
         'subject': 'world',
         'dash-dash': 'dash',
         'space space': 'space'
       };
       
       Alloy.Models.modelb.set({
         'mix it': 'Mix It!',
         deep: {
           link: 'deep-link'
         }
       });
       
       Alloy.Models['model-a'].set(attributes);
       Alloy.Collections['model-a'].reset([attributes]);
       
       $.index.open();
       
    *model-a.js*
       exports.definition = {
         extendModel: function(Model) {
           _.extend(Model.prototype, {
             transform: function() {
               var transformed = this.toJSON();
       
               transformed.subject && (transformed.subject = transformed.subject.toUpperCase());
               transformed.font = {
                 fontSize: 20,
                 fontWeight: 'bold'
               };
       
               return transformed;
             }
           });
       
           return Model;
         }
       };
       
    *modelb.js*
       exports.definition = {};
       
    Is this a limitation of _.template() that we cannot overcome? Can this get another look?
  5. Feon Sua Xin Miao 2016-08-03

    [~ewieber] I looked at this for a bit, the limitation is to use square bracket notation, \[' '], for attributes with properties containing special characters.
       <Alloy>
       	<Model src="model-a" />
       	<Model src="modelb" />
       	<Collection src="model-a" />
       	<Window backgroundColor="white" layout="vertical">
       		<Label top="20" font="{['model-a'].font}" text="{['model-a'].greeting} {modelb['mix it']}" />
       		<Label font="{['model-a'].font}" text="well {['model-a'].greeting}" />
       		<Label font="{['model-a'].font}" text="{['model-a'].greeting} {modelb.deep.link}!" />
       		<Label font="{['model-a'].font}" text="well {['model-a'].greeting} there's {['model-a'].subject}!" />
       		<Label font="{['model-a'].font}" text="well {['model-a']['dash-dash']} there's {['model-a'].subject}!" />
       		<ListView height="Ti.UI.SIZE" canScroll="false">
       			<ListSection dataCollection="model-a">
       				<ListItem font="{font}" title="well {['dash-dash']} there {['space space']}!" />
       			</ListSection>
       		</ListView>
       	</Window>
       </Alloy>
       
       
  6. Eric Wieber 2016-08-04

    Thank you for the second look [~fmiao]. Looking at the first half of the test case, knowing about the square brackets, makes it seem obvious now, but I do not see this notation documented anywhere. [~bimmel], It may be worth noting in the [Alloy Data Binding](http://docs.appcelerator.com/platform/latest/#!/guide/Alloy_Data_Binding) docs that the square bracket notation should be used for referencing model attributes with special characters in their names. That said: Verified fixed using: MacOS 10.11.5 (15F31a) Studio 4.7.0.201607250649 Ti SDK 5.4.0.v20160802165655 Appc NPM 4.2.7 Appc CLI 5.4.0-37 Alloy 1.9.1 Xcode 7.3.1 (7D1014) Projects compile and run correctly when using data binding with models who's attributes contain spaces, dashes, and quotes. Tested using the provided sample code, tests in the Alloy repo (both modified to use the square bracket notation for collections), and personal test apps.

JSON Source