{ "id": "104330", "key": "ALOY-362", "fields": { "issuetype": { "id": "2", "description": "A new feature of the product, which has yet to be developed.", "name": "New Feature", "subtask": false }, "project": { "id": "11113", "key": "ALOY", "name": "Alloy", "projectCategory": { "id": "10400", "description": "Tools for developing applications", "name": "Tooling" } }, "fixVersions": [ { "id": "15758", "description": "Alloy 1.4.0", "name": "Alloy 1.4.0", "archived": false, "released": true, "releaseDate": "2014-07-17" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2014-05-21T15:18:42.000+0000", "created": "2012-11-02T18:37:47.000+0000", "priority": { "name": "Medium", "id": "3" }, "labels": [ "notable", "qe-testadded" ], "versions": [], "issuelinks": [ { "id": "37125", "type": { "id": "10000", "name": "Blocks", "inward": "is blocked by", "outward": "blocks" }, "inwardIssue": { "id": "129714", "key": "TIDOC-1640", "fields": { "summary": "Alloy: add documentation for using controller-less views (ALOY-362)", "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": "High", "id": "2" }, "issuetype": { "id": "2", "description": "A new feature of the product, which has yet to be developed.", "name": "New Feature", "subtask": false } } } } ], "assignee": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "updated": "2014-05-22T21:52:04.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": "12329", "name": "Runtime", "description": "Generic bucket for uncategorized runtime issues" } ], "description": "The ability to create views without a controller is quite nice, but it could be taken a step further. During development of a recent application I built numerous controllers with only 1 or 2 lines of code to set properties of elements in the view. For example:\r\n\r\n{code:JavaScript|title=Index.js}\r\nAlloy.createController(\"MyView\", {\r\n\tlabelText: \"Hello, World!\",\r\n\timageUrl: \"/images/test.png\"\r\n}).getView();\r\n{code}\r\n\r\n{code:JavaScript|title=MyView.js}\r\n$.MyLabel.text = arguments[0].labelText;\r\n$.MyImage.image = arguments[0].imageUrl;\r\n{code}\r\n\r\nIt would be nice if we could pass in parameters to the controller-less view which automatically sets these properties. For example:\r\n\r\n{code:JavaScript|title=Index.js}\r\nAlloy.createController(\"MyView\", {\r\n\tMyLabel: {\r\n\t\ttext: \"Hello, World!\"\r\n\t},\r\n\tMyImage: {\r\n\t\timage: \"/images/test.png\"\r\n\t}\r\n}).getView();\r\n{code}\r\n\r\nThis lets us omit the controller completely.", "attachment": [], "flagged": false, "summary": "Allow controller-less views with some controller logic", "creator": { "name": "matthewcongrove", "key": "matthewcongrove", "displayName": "Matthew Congrove", "active": true, "timeZone": "America/Chicago" }, "subtasks": [], "reporter": { "name": "matthewcongrove", "key": "matthewcongrove", "displayName": "Matthew Congrove", "active": true, "timeZone": "America/Chicago" }, "environment": null, "closedSprints": [ { "id": 50, "state": "closed", "name": "2014 Sprint 09 Tooling", "startDate": "2014-04-28T15:43:24.381Z", "endDate": "2014-05-10T03:44:00.000Z", "completeDate": "2014-05-12T13:36:16.254Z", "originBoardId": 113 } ], "comment": { "comments": [ { "id": "226013", "author": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "body": "I like this idea, with a small change to implementation likely. For the sake of keeping the current convention unchanged, I would prefer to use a spceific reserved property where these \"by id\" property assignments would happen. Something like:\r\n\r\n{code:lang=javascript}\r\nAlloy.createController(\"MyView\", {\r\n views: {\r\n MyLabel: {\r\n text: \"Hello, World!\"\r\n },\r\n MyImage: {\r\n image: \"/images/test.png\"\r\n }\r\n }\r\n}).getView();\r\n{code}\r\n\r\nor perhaps like this:\r\n\r\n{code:lang=javascript}\r\nAlloy.createController(\"MyView\", {\r\n '#MyLabel': {\r\n text: \"Hello, World!\"\r\n },\r\n '#MyImage': {\r\n image: \"/images/test.png\"\r\n }\r\n}).getView();\r\n{code}\r\n\r\njust looking to avoid conflicts with how people currently use it", "updateAuthor": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2012-11-02T19:12:27.000+0000", "updated": "2012-11-02T19:13:35.000+0000" }, { "id": "226014", "author": { "name": "matthewcongrove", "key": "matthewcongrove", "displayName": "Matthew Congrove", "active": true, "timeZone": "America/Chicago" }, "body": "Yes, that makes much more sense. I really like the latter as it keeps everything similar across the filetypes (JS -> TSS).", "updateAuthor": { "name": "matthewcongrove", "key": "matthewcongrove", "displayName": "Matthew Congrove", "active": true, "timeZone": "America/Chicago" }, "created": "2012-11-02T19:15:34.000+0000", "updated": "2012-11-02T19:15:34.000+0000" }, { "id": "300098", "author": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "body": "PR: https://github.com/appcelerator/alloy/pull/358\n\nFunctional test:\n\nRun the app included in the PR. The result should be a white window with two labels: the first with a large gradient background and other properties as set in the index.js controller. Note that the childview.xml contains no properties other than ID. Styles from childview.tss are merged in. There is no childview.js controller file. Properties and values are set in the index.js controller using the new autoView argument.", "updateAuthor": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "created": "2014-04-07T20:45:56.000+0000", "updated": "2014-04-07T20:45:56.000+0000" }, { "id": "302706", "author": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "body": "reopened for alternative implementation", "updateAuthor": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "created": "2014-04-28T15:05:11.000+0000", "updated": "2014-04-28T15:05:11.000+0000" }, { "id": "302707", "author": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "body": "New PR: https://github.com/appcelerator/alloy/pull/376 \r\n\r\nFunctional test as before.\r\n\r\nIn the new implementation, you no longer use the \"autoView\" object in your createController() call. Instead, pass an argument object whose keys correspond to the IDs of the components in the child view to which the styles will be applied.\r\n\r\n{code}\r\n$.index.add(Alloy.createController('childview', {\r\n\t\"#label\": {\r\n\t\ttext: 'I am a label',\r\n\t\ttop: 50\r\n\t},\r\n\t\"#anotherlabel\": {\r\n\t\ttext: 'I am also a label',\r\n\t\tfoo: 'bar' /* a custom/non-existent property */\r\n\t},\r\n\t\"#someNonExistentId\": { text: 'I do not exist'}\r\n}).getView());\r\n{code}", "updateAuthor": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "created": "2014-04-28T15:28:04.000+0000", "updated": "2014-04-28T15:28:04.000+0000" }, { "id": "302750", "author": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "body": "For performance reasons, I'm leaning towards the implementation of https://github.com/appcelerator/alloy/pull/377 \r\n\r\n{code}\r\n$.index.add(Alloy.createController('childview', {\r\n alloyAutoView: {\r\n \"#label\": {\r\n text: 'I am a label',\r\n top: 50\r\n },\r\n \"#anotherlabel\": {\r\n text: 'I am also a label',\r\n foo: 'bar'\r\n },\r\n \"#someNonExistentId\": { text: 'I do not exist'}\r\n }\r\n}).getView());\r\n{code}", "updateAuthor": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "created": "2014-04-28T17:29:35.000+0000", "updated": "2014-04-28T17:29:35.000+0000" }, { "id": "302899", "author": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "body": "OK, I went with a new dedicated method for controller-less views. This offers the best performance for existing apps and \"standard\" functionality while making controllerless views available to developers via a specific method.\r\n\r\nSee https://github.com/appcelerator/alloy/pull/376 (merged).\r\n\r\n{code}\r\n// new method, for instantiating controllerless views\r\n$.index.add(Alloy.createControllerlessView('childview', {\r\n \"#label\": {\r\n text: 'I am a label',\r\n top: 50\r\n }\r\n}).getView());\r\n\r\n// old method for instantiating controllers is still there\r\n$.index.add(Alloy.createController('normalchild', {\r\n\ttext: 'Set the old-fashioned way in the normalchild.js file'\r\n}).getView());\r\n{code}\r\n\r\nFinal functional test:\r\n\r\nRun the ALOY-362 test app. The result should be a white window with three labels: the top two are created with the controllerless view technique. The first label has a large gradient background and other properties as set in the index.js controller. Note that the childview.xml contains no properties other than ID. Styles from childview.tss are merged in. There is no childview.js controller file. Properties and values are set in the index.js controller using the new autoView argument. A third label, at the bottom of the screen is created with the traditional createController() method.\r\n", "updateAuthor": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "created": "2014-04-29T17:25:26.000+0000", "updated": "2014-04-29T17:25:26.000+0000" }, { "id": "302900", "author": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "body": "PR merged", "updateAuthor": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "created": "2014-04-29T17:25:38.000+0000", "updated": "2014-04-29T17:25:38.000+0000" }, { "id": "305349", "author": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "body": "re-open for potential api change", "updateAuthor": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-05-16T20:16:36.000+0000", "updated": "2014-05-16T20:16:36.000+0000" }, { "id": "305735", "author": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "body": "The new API moves this functionality to be a method of the controller, which must be invoked after the controller is instantiated. Like this:\r\n\r\n{code}\r\nvar someView = Alloy.createController('someView');\r\nsomeView.updateViews({\r\n \"#myLabel\": {\r\n text: 'I am a label',\r\n top: 50\r\n }\r\n});\r\n$.index.add(someView.getView());\r\n{code}\r\n\r\nNote that updateViews() will not apply attributes to or elements within your new controller. ", "updateAuthor": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "created": "2014-05-20T17:55:51.000+0000", "updated": "2014-05-20T17:55:51.000+0000" }, { "id": "305738", "author": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "body": "New PR https://github.com/appcelerator/alloy/pull/404\r\n\r\nMerged to 1_4_X branch and cherry-picked to master", "updateAuthor": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "created": "2014-05-20T18:00:11.000+0000", "updated": "2014-05-20T18:00:11.000+0000" }, { "id": "305923", "author": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "body": "Problem on Android was due to case -- sample app used normalChild when the file was named normalchild. The sample app would have failed on an iOS device. I've corrected that. I also made a change that removes an inadvertent SDK dependency (as written, the solution would have required SDK 3.2.0+).", "updateAuthor": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "created": "2014-05-21T15:18:32.000+0000", "updated": "2014-05-21T15:18:32.000+0000" }, { "id": "305924", "author": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "body": "New PR https://github.com/appcelerator/alloy/pull/408 has been merged to 1_4_X and master", "updateAuthor": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "created": "2014-05-21T15:18:42.000+0000", "updated": "2014-05-21T15:18:42.000+0000" }, { "id": "306151", "author": { "name": "fcasali", "key": "fcasali", "displayName": "Federico Casali", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Verified fixed and working as expected on Android (Google Nexus Galaxy), iOS (iPhone 5) and MobileWeb\r\n\r\nTiSDK 3.3.0.v20140522110830\r\nAlloy 1.4.0-alpha4\r\nAppcelerator Studio 3.3.0.201405211748\r\nCLI 3.3.0-alpha5\r\n\r\nClosing.", "updateAuthor": { "name": "fcasali", "key": "fcasali", "displayName": "Federico Casali", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-05-22T21:51:59.000+0000", "updated": "2014-05-22T21:51:59.000+0000" } ], "maxResults": 17, "total": 17, "startAt": 0 } } }