{ "id": "111280", "key": "ALOY-602", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "11113", "key": "ALOY", "name": "Alloy", "projectCategory": { "id": "10400", "description": "Tools for developing applications", "name": "Tooling" } }, "fixVersions": [], "resolution": { "id": "5", "description": "All attempts at reproducing this issue failed, or not enough information was available to reproduce the issue. Reading the code produces no clues as to why this behavior would occur. If more information appears later, please reopen the issue.", "name": "Cannot Reproduce" }, "resolutiondate": "2013-04-22T22:47:47.000+0000", "created": "2013-03-16T17:01:07.000+0000", "priority": null, "labels": [], "versions": [], "issuelinks": [], "assignee": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2014-01-29T00:07:25.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [], "description": "First things first: I'm using the current master of alloy and titanium SDK (as of right now). I don't use Titanium Studio. I only use the CLI. I'm only developing for Android (API level 14) right now.\r\n\r\nI have two simple backbone collections defined in alloy.js:\r\n{code}\r\nvar CharacterCollection = Backbone.Collection.extend({\r\n\tcomparator: function(model){\r\n\t\treturn model.get('name');\r\n\t}\r\n});\r\nvar SystemCollection = Backbone.Collection.extend({\r\n\tcomparator: function(model){\r\n\t\treturn model.get('system');\r\n\t}\r\n});\r\n\r\nvar characters = new CharacterCollection([\r\n\t{name: 'Name1', system:'System1'},\r\n\t{name: 'Name2', system:'System2'},\r\n\t{name: 'Name3', system:'System3'}\r\n]);\r\n\r\nvar systems = new SystemCollection([\r\n\t{system:'System1'},\r\n\t{system:'System2'},\r\n\t{system:'System3'}\r\n]);\r\n\r\nAlloy.Collections.characters = characters;\r\nAlloy.Collections.systems = systems;\r\n{code}\r\n\r\nI want to display a table with all characters, but grouped in TableViewSections for each system they belong to.\r\n\r\nSo I created the following views:\r\n\r\n_index.xml_\r\n{code}\r\n\r\n \r\n \r\n \r\n\r\n{code}\r\n\r\n_charactersBySystem.xml_\r\n{code}\r\n\r\n \r\n \r\n \r\n\r\n{code}\r\n\r\n_characterTableRow.xml_\r\n{code}\r\n\r\n \r\n\r\n{code}\r\n\r\nFor those views I have the following controllers:\r\n\r\n_index.js_\r\n{code}\r\nvar CharacterModel = Backbone.Model.extend(),\r\n characterCollection = Alloy.Collections.characters,\r\n systemCollection = Alloy.Collections.systems;\r\n\r\n$.index.open();\r\n\r\nsystemCollection.trigger(\"change\");\r\n{code}\r\n\r\n_charactersBySystem.js_\r\n{code}\r\nvar arguments = arguments || {},\r\n args = arguments[0] || {},\r\n systemName = args.system || 'None',\r\n characterCollection = Alloy.Collections.characters;\r\n\r\nfunction filterCharactersBySystem(collection) {\r\n return collection.where({system: systemName});\r\n}\r\n\r\n$.tableSection.headerTitle = systemName;\r\n\r\ncharacterCollection.trigger(\"change\");\r\n{code}\r\n\r\n_characterTableRow.js_\r\n{code}\r\nvar arguments = arguments || {},\r\n args = arguments[0] || {},\r\n characterName = args.characterName || 'None';\r\n\r\n$.characterTableRow.title = characterName;\r\n{code}\r\n\r\nNow if I run this code I get a table that looks like this:\r\n||System1||\r\n|Name1|\r\n|Name1|\r\n|Name1|\r\n||System2||\r\n|Name2|\r\n|Name2|\r\n||System3||\r\n|Name3|\r\n\r\nBut I would expect to see:\r\n||System1||\r\n|Name1|\r\n||System2||\r\n|Name2|\r\n||System3||\r\n|Name3|\r\n\r\nThis seems to be a bug. Or am I missing something?", "attachment": [], "flagged": false, "summary": "Nested collection bindings don't work as expected", "creator": { "name": "examinator", "key": "examinator", "displayName": "Steven Weingärtner", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "penrique", "key": "penrique", "displayName": "Pedro Enrique", "active": false, "timeZone": "America/Los_Angeles" }, "environment": "Windows 7", "comment": { "comments": [ { "id": "242910", "author": { "name": "dcassenti", "key": "dcassenti", "displayName": "Davide Cassenti", "active": true, "timeZone": "Europe/Berlin" }, "body": "Hello,\n\nIt looks like the problem is due to the fact that you are firing the change manually inside charactersBySystem.js; the problem here is that this code is executed multiple times, while it should only be called once:\n\n{code}\ncharacterCollection.trigger(\"change\");\n{code}\n\nBy moving the trigger in index.js, the problem looks fixed to me.\n", "updateAuthor": { "name": "dcassenti", "key": "dcassenti", "displayName": "Davide Cassenti", "active": true, "timeZone": "Europe/Berlin" }, "created": "2013-03-19T14:50:34.000+0000", "updated": "2013-03-19T14:50:34.000+0000" }, { "id": "242973", "author": { "name": "examinator", "key": "examinator", "displayName": "Steven Weingärtner", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Hi,\n\nI tried that right now, but it didn't work.\n\nWhen I move\n{code}\ncharacterCollection.trigger(\"change\");\n{code}\nto index.js, it doesn't seem to do anything. I just get the empty sections, without the actual table rows. And this seems kind of counter intuitive, too. I might trigger the change event multiple times, but shouldn't it recognize which elements within the collection have already been processed? What would happen if I add an element to the collection? That would just trigger the change event again, wouldn't it? So would it add ALL elements within the collection again without removing the old ones first?\n\nThanks!", "updateAuthor": { "name": "examinator", "key": "examinator", "displayName": "Steven Weingärtner", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-03-19T18:35:11.000+0000", "updated": "2013-03-19T18:35:11.000+0000" }, { "id": "242997", "author": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "body": "No, it processes the current state of the collection. It doesn't keep track of what your code does or does not do leading up to the execution of the triggered change event. If you add an element to the collection the binding will be triggered and an \"add\" event will be triggered as stated in the [Backbone documentation for add()|http://backbonejs.org/#Collection-add]. Each time the binding is triggered the target UI element is emptied and then repopulated with the current state of the collection.\n\ndavide, could you share your modified code to show how the proper state can be achieved?", "updateAuthor": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-03-19T19:04:43.000+0000", "updated": "2013-03-19T19:04:43.000+0000" }, { "id": "243153", "author": { "name": "dcassenti", "key": "dcassenti", "displayName": "Davide Cassenti", "active": true, "timeZone": "Europe/Berlin" }, "body": "My code is simple:\r\n\r\n_index.js_\r\n{code}\r\nvar CharacterModel = Backbone.Model.extend(),\r\n characterCollection = Alloy.Collections.characters,\r\n systemCollection = Alloy.Collections.systems;\r\n\r\n$.index.open();\r\n\r\nsystemCollection.trigger(\"change\");\r\ncharacterCollection.trigger(\"change\");\r\n{code}\r\n\r\n_charactersBySystem.js_\r\n{code}\r\nvar arguments = arguments || {},\r\n args = arguments[0] || {},\r\n systemName = args.system || 'None',\r\n characterCollection = Alloy.Collections.characters;\r\n\r\nfunction filterCharactersBySystem(collection) {\r\n return collection.where({system: systemName});\r\n}\r\n\r\n$.tableSection.headerTitle = systemName;\r\n{code}\r\n\r\n_characterTableRow.js_\r\n{code}\r\nvar arguments = arguments || {},\r\n args = arguments[0] || {},\r\n characterName = args.characterName || 'None';\r\n\r\n$.characterTableRow.title = characterName;\r\n{code}", "updateAuthor": { "name": "dcassenti", "key": "dcassenti", "displayName": "Davide Cassenti", "active": true, "timeZone": "Europe/Berlin" }, "created": "2013-03-20T15:18:53.000+0000", "updated": "2013-03-20T15:20:54.000+0000" }, { "id": "243458", "author": { "name": "examinator", "key": "examinator", "displayName": "Steven Weingärtner", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Ok, just some more tests:\nI used the code I posted above (with the addition of a window element, which I forget to add to the index.xml file above).\nThen I copy/pasted Davids code and replaced mine with it.\n\nFirst I tried it on SDK version 3.1.0.v20130315162454.\nThis only gives me the empty table view sections, sying System1, System2 and System3, but without any characters listed beneath.\n\nThen I tried to fall back to SDK version 3.0.2.GA, which gives me a blank page with nothing but the action bar that shows the title and icon of my app.\n\nThen I tried to updated to master (SDK version 3.1.0.v20130321102915).\nThis gives me an error when I try to build the app: \n{code}\n[ERROR] : \b\b \bTypeError: Cannot read property 'length' of undefined\n{code}\n\nAnyway, I'll try to figure that last error out. But what exact SDK version did you use?", "updateAuthor": { "name": "examinator", "key": "examinator", "displayName": "Steven Weingärtner", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-03-21T18:02:51.000+0000", "updated": "2013-03-21T18:02:51.000+0000" }, { "id": "245936", "author": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "body": "@Davide, can you make sure you and Steven are using the same environment? See if you guys can get synced up on why he can't get your sample working.", "updateAuthor": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-04-05T12:12:21.000+0000", "updated": "2013-04-05T12:12:21.000+0000" }, { "id": "246875", "author": { "name": "dcassenti", "key": "dcassenti", "displayName": "Davide Cassenti", "active": true, "timeZone": "Europe/Berlin" }, "body": "I've been using the GA version. Can you post the last version of your files, so I can give it another look at?", "updateAuthor": { "name": "dcassenti", "key": "dcassenti", "displayName": "Davide Cassenti", "active": true, "timeZone": "Europe/Berlin" }, "created": "2013-04-10T16:54:35.000+0000", "updated": "2013-04-10T16:54:35.000+0000" }, { "id": "248687", "author": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Closing this ticket until more details are provided for Davide to test.", "updateAuthor": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-04-22T22:47:47.000+0000", "updated": "2013-04-22T22:47:47.000+0000" } ], "maxResults": 8, "total": 8, "startAt": 0 } } }