{ "id": "111278", "key": "ALOY-603", "fields": { "issuetype": { "id": "4", "description": "An improvement or enhancement to an existing feature or task.", "name": "Improvement", "subtask": false }, "project": { "id": "11113", "key": "ALOY", "name": "Alloy", "projectCategory": { "id": "10400", "description": "Tools for developing applications", "name": "Tooling" } }, "fixVersions": [ { "id": "15403", "description": "Alloy 1.3.0", "name": "Alloy 1.3.0", "archived": false, "released": true, "releaseDate": "2013-12-20" }, { "id": "15753", "description": "2013 Sprint 22", "name": "2013 Sprint 22", "archived": true, "released": true, "releaseDate": "2013-11-01" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2014-08-29T09:09:54.000+0000", "created": "2013-03-16T12:24:35.000+0000", "priority": { "name": "Medium", "id": "3" }, "labels": [ "alloy", "notable", "qe-automatedtest", "qe-manualtest", "views", "widgets", "xml" ], "versions": [], "issuelinks": [ { "id": "33332", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "inwardIssue": { "id": "122795", "key": "ALOY-883", "fields": { "summary": "Support proxy-like elements in Alloy widget/require child view-elements", "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" } }, "priority": { "name": "Medium", "id": "3" }, "issuetype": { "id": "2", "description": "A new feature of the product, which has yet to be developed.", "name": "New Feature", "subtask": false } } } } ], "assignee": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2014-09-02T23:14:35.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": [ { "id": "12326", "name": "XML", "description": "View XML and parsing" } ], "description": "h2. update (10/25/2013)\r\n\r\nThis has been resolved in a way different than the original description. It is implemented in the example found here: https://github.com/appcelerator/alloy/tree/master/test/apps/advanced/require_children\r\n\r\nIn brief, any child elements of or elements will be passed to that widget's controller as an array, and it will be contained in {{args.children}}. Here's a trivial example using , but it works exactly the same for as well:\r\n\r\nh4. index.xml\r\n{code:xml}\r\n\r\n \r\n \r\n \r\n \r\n \r\n\r\n{code}\r\n\r\nh4. someRequire.xml\r\n{code:xml}\r\n\r\n \r\n\r\n{code}\r\n\r\nh4. someRequire.js\r\n{code:javascript}\r\nvar args = arguments[0] || {},\r\n\r\n // args.children contains the elements under the elements, if any\r\n children = args.children || [];\r\n\r\n// add child views to content\r\n_.each(children, function(child) {\r\n $.content.add(child);\r\n});\r\n{code}\r\n\r\nh2. original\r\n\r\nFollowing the discussion at https://groups.google.com/d/msg/appc-ti-alloy/8PVVSE1UzXE/x6frOeTZGd4J I propose to add support for child elements in {{}} elements in Alloy XML views.\r\n\r\nThe purpose of this would be to get a reference of these elements from within a widget that doesn't return a view of it's own, but is designed to act upon others. It would function in a way not that different from the existing support for getting a reference of the Widget parent element using {{this.parent}}.\r\n\r\n*Example XML View*\r\n\r\n{code}\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n{code}\r\n\r\n*Would be compiled to*\r\n\r\n{code}\r\n...\r\n$.myWidget = Alloy.createWidget(\"my.alloy.widget\", \"widget\", {\r\n id: \"myWidget\"\r\n});\r\n$.myWidget.setParent($.__views.myWindow);\r\n$.myWidget.setChildren([$.__views.myTable]);\r\n...\r\n{code}\r\n\r\n*Notes*\r\nSince the widget does not provide a view it's stored in {{$.ID}} instead of {{$.__views.ID}}. Because the widget could contain multiple child elements the methods is {{setChildren}} and it accepts an array.\r\n", "attachment": [ { "id": "43463", "filename": "Screen Shot 2013-10-25 at 4.19.39 PM.png", "author": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-10-25T20:35:20.000+0000", "size": 36179, "mimeType": "image/png" }, { "id": "43464", "filename": "Screen Shot 2013-10-25 at 4.19.47 PM.png", "author": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-10-25T20:35:20.000+0000", "size": 75036, "mimeType": "image/png" } ], "flagged": false, "summary": "Allow Alloy widgets to be wrapped around child elements in XML views", "creator": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "subtasks": [], "reporter": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "environment": "Any", "comment": { "comments": [ { "id": "247908", "author": { "name": "dcassenti", "key": "dcassenti", "displayName": "Davide Cassenti", "active": true, "timeZone": "Europe/Berlin" }, "body": "Is there any progress about this?", "updateAuthor": { "name": "dcassenti", "key": "dcassenti", "displayName": "Davide Cassenti", "active": true, "timeZone": "Europe/Berlin" }, "created": "2013-04-17T09:52:12.000+0000", "updated": "2013-04-17T09:52:12.000+0000" }, { "id": "247922", "author": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "body": "No, not at this time. There's a number of high priority tickets I need to get to before I'll be able to get back to this one. I don't have a reliable ETA for it yet.", "updateAuthor": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-04-17T12:59:13.000+0000", "updated": "2013-04-17T12:59:13.000+0000" }, { "id": "262598", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "Huh? How come Pedro is now the reporter? I thought I was..\r\n\r\nAnyway, another use case I would like to use this for is:\r\n\r\n{code}\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n{code}\r\n\r\nThe widget would return a `Ti.UI.iPhone.NavigationGroup` on iOS, while just open `Window#primary` on other platforms, so you have a cross platform solution. Additionally, both the iOS and other implementation could add additional methods for closing the last window or close all but the first.", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2013-07-21T12:38:30.000+0000", "updated": "2013-07-21T12:38:30.000+0000" }, { "id": "262613", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "Same is true for {{}}. A sample use case would be to have a view/controller that is used in multiple other views to wrap their content in a custom popup, without having to repeat the same view elements in every of these views:\r\n\r\nView using the wrapper:\r\n{code}\r\n\r\n \r\n \r\n \r\n\r\n{code}\r\n\r\nView of the wrapper:\r\n\r\n{code}\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n{code}\r\n\r\nController of the wrapper:\r\n\r\n{code}\r\nfunction closeDialog() {\r\n $.getView().close();\r\n}\r\n\r\nexports.add = $.content.add;\r\n{code}\r\n\r\nThe above controller code also shows that the controller should expose an {{add}} method that receives the first level of wrapped view(s) so it can consume them in whatever way it needs to.", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2013-07-21T18:19:23.000+0000", "updated": "2013-07-21T18:19:39.000+0000" }, { "id": "262658", "author": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~fokke] pedro probably moved it from TC to ALOY, and sometimes that inadvertantly reassigns the reporter. I fixed it.", "updateAuthor": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-07-22T14:39:29.000+0000", "updated": "2013-07-22T14:39:29.000+0000" }, { "id": "262805", "author": { "name": "ronaldtreur", "key": "ronaldtreur", "displayName": "Ronald Treur", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "Thanks again Fokke for bringing this up! I'm very happy to see it will be included in the near future.\r\n\r\nI originally wanted to wrap the Ti.UI.Window in a widget, but had to reside to windows registering themselves with a custom manager upon creation. This fix/feature will make sure use-cases like this one will utilize the full potential of Alloy's XML Views.\r\n\r\nKudos to all involved!", "updateAuthor": { "name": "ronaldtreur", "key": "ronaldtreur", "displayName": "Ronald Treur", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2013-07-23T10:24:30.000+0000", "updated": "2013-07-23T10:24:30.000+0000" }, { "id": "263562", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "It seems to work for me by changing just a few lines:\r\n\r\n{{Alloy.Require.js#26}}\r\n{code}\r\n //U.die(' elements may not have child elements.');\r\n{code}\r\n\r\n{{Alloy.Require.js#122}}\r\n{code}\r\n symbolic: args.symbol,\r\n symbol: args.symbol + '.getViewEx({recurse:true})'\r\n{code}\r\n\r\n{{default.js#98}}\r\n{code}\r\n code += (args.parent.symbolic || args.parent.symbol) + \".add(\" + args.symbol + \");\\n\";\r\n{code}\r\n\r\nI'm sure there are things to take care off, but this will expect an {{add}} method to be exposed by the Widget/Controller, which could then do whatever it wants with the added child view(s).", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2013-07-27T19:38:43.000+0000", "updated": "2013-07-27T19:38:43.000+0000" }, { "id": "265456", "author": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "body": "I'm starting to think about this one, and I think I want to put all the effort onto the widget developer to determine what is done with the children. I don't think a new add() API needs to be introduced for the requires/widgets, it should be the responsibility of the widget designer to handle them. \n\nhere's a very basic gist of how I would imagine you would implement this behavior, assuming that Alloy provided a \"children\" argument to widgets/requires:\n\nhttps://gist.github.com/tonylukasavage/6178871\n\nI'd like to keep the implementation simple to see what particular use cases rise up around it. In the future we could designate an XML attribute on or in the widget that identifies the \"container\" component so that you don't need to assemble the view hierarchy programmatically, but I think this is a good first step and that type of functionality can easily be added later if this proves useful.\n\nThoughts? ", "updateAuthor": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-08-07T21:29:09.000+0000", "updated": "2013-08-07T21:29:09.000+0000" }, { "id": "265531", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "Looks pretty solid, you could even support doing stuff like this:\r\n\r\n{code}\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n{code}\r\n\r\nTo be passed as:\r\n\r\n{code}\r\nchildren: {\r\n SomeProxy: {\r\n children: [\r\n [object Ti.UI.Button]\r\n ]\r\n },\r\n AnotherProxy: {\r\n children: [\r\n [object Ti.UI.Button],\r\n [object Ti.UI.Button],\r\n ]\r\n },\r\n children: [\r\n [object Ti.UI.Button]\r\n ]\r\n}\r\n{code}\r\n\r\nThis might seem like a bit too much, but imagine having a widget taking a table, a view for the Pull to Refresh, another for the Infinite Scroll.", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2013-08-08T07:16:38.000+0000", "updated": "2013-08-08T07:16:38.000+0000" }, { "id": "265535", "author": { "name": "ronaldtreur", "key": "ronaldtreur", "displayName": "Ronald Treur", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "Looks like a very flexible solution to me, I like it!", "updateAuthor": { "name": "ronaldtreur", "key": "ronaldtreur", "displayName": "Ronald Treur", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2013-08-08T08:51:52.000+0000", "updated": "2013-08-08T08:51:52.000+0000" }, { "id": "276844", "author": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "body": "PR: https://github.com/appcelerator/alloy/pull/258\r\ntest app: https://github.com/appcelerator/alloy/tree/master/test/apps/advanced/require_children\r\n\r\nFunctional test should include the following for all supported platforms:\r\n\r\n# Run the app\r\n# Ensure that no compile time or runtime errors occur\r\n# Ensure that the resulting UI is composed of the child elements contained in the and elements in the app\r\n# For reference, the iOS 7 screens should look like the attached screenshots (ignore the missing tab titles, its a result of TIMOB-15581)\r\n\r\nAll {{jake test:all}} tests should pass as well.\r\n", "updateAuthor": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-10-25T20:34:59.000+0000", "updated": "2013-10-25T20:34:59.000+0000" }, { "id": "280508", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2013-11-21T07:49:44.000+0000", "updated": "2013-11-21T07:49:44.000+0000" }, { "id": "280528", "author": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~fokke] I think a new ticket that better details the format and expected behavior would be appropriate. I'm a little foggy on what you are trying to do there, if only because I think you are using the word \"proxy\" differently than we typically use it. If you do create a ticket, mention this one and I'll make sure they get linked.", "updateAuthor": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-11-21T12:08:39.000+0000", "updated": "2013-11-21T12:09:10.000+0000" }, { "id": "280707", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "[~tlukasavage] here it is: TC-3318", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2013-11-22T08:46:49.000+0000", "updated": "2013-11-22T08:46:49.000+0000" }, { "id": "282028", "author": { "name": "fcasali", "key": "fcasali", "displayName": "Federico Casali", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Verified fixed.\n\nTiSDK 3.2.0.v20131127194046\nCLI 3.2.0-beta\nAlloy 1.3.0-beta\nTitanium Studio 3.2.0.201311262027\n\niPad OS 7 and simulator\nAndroid Google Nexus Galaxy 4.3\nMobileWeb (for sample #2)\n\nClosing.", "updateAuthor": { "name": "fcasali", "key": "fcasali", "displayName": "Federico Casali", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-12-03T00:32:10.000+0000", "updated": "2013-12-03T00:32:10.000+0000" }, { "id": "320889", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~fcasali] should this be closed?", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-08-28T21:28:01.000+0000", "updated": "2014-08-28T21:28:01.000+0000" }, { "id": "320970", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "Yes", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2014-08-29T06:35:18.000+0000", "updated": "2014-08-29T06:35:18.000+0000" }, { "id": "321472", "author": { "name": "fcasali", "key": "fcasali", "displayName": "Federico Casali", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Yes, it should. Closing.", "updateAuthor": { "name": "fcasali", "key": "fcasali", "displayName": "Federico Casali", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-09-02T23:14:30.000+0000", "updated": "2014-09-02T23:14:30.000+0000" } ], "maxResults": 20, "total": 20, "startAt": 0 } } }