{ "id": "171280", "key": "ALOY-1610", "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": [], "resolution": null, "resolutiondate": null, "created": "2018-03-09T09:33:44.000+0000", "priority": { "name": "None", "id": "6" }, "labels": [ "alloy", "controller", "demo_app", "tss" ], "versions": [ { "id": "20117", "name": "Alloy 1.11.0", "archived": false, "released": true } ], "issuelinks": [], "assignee": { "name": "fmiao", "key": "fmiao", "displayName": "Feon Sua Xin Miao", "active": true, "timeZone": "America/Vancouver" }, "updated": "2019-03-11T19:54:35.000+0000", "status": { "description": "The issue is open and ready for the assignee to start work on it.", "name": "Open", "id": "1", "statusCategory": { "id": 2, "key": "new", "colorName": "blue-gray", "name": "To Do" } }, "components": [ { "id": "13603", "name": "Styling", "description": "TSS, dynamic styling, styling API" }, { "id": "12326", "name": "XML", "description": "View XML and parsing" } ], "description": "In a TSS file only variables created on the Alloy namespace are to be used inside the TSS files. This creates anti-patterns with modules for example.\r\n\r\nSituation right now:\r\n\r\n{code}\r\n// alloy.js\r\nAlloy.Globals.Map = require('ti.map');\r\n\r\n//mapview.tss\r\n pattern: {\r\n type: Alloy.Globals.Map.POLYLINE_PATTERN_DASHED,\r\n gapLength: 15,\r\n dashLength: 3\r\n }\r\n{code}\r\n\r\nPreferred flow would be to not pollute the global namespace for multiple reasons (memory usage and app startup time. Something like this:\r\n\r\n{code}\r\n// mapview.js\r\nvar timap = require('ti.map');\r\n\r\n// mapview.tss\r\n type: timap.POLYLINE_PATTERN_DASHED,\r\n{code}\r\nOr if namespacing is important, maybe use the $ namespace like this\r\n\r\n{code}\r\n// mapview.js\r\n$.timap = require('ti.map');\r\n\r\n// mapview.tss\r\n type: $.timap.POLYLINE_PATTERN_DASHED,\r\n{code}", "attachment": [], "flagged": false, "summary": "Allow controller created variables to be used in tss", "creator": { "name": "topener", "key": "topener", "displayName": "Rene Pot", "active": true, "timeZone": "Europe/Berlin" }, "subtasks": [], "reporter": { "name": "topener", "key": "topener", "displayName": "Rene Pot", "active": true, "timeZone": "Europe/Berlin" }, "environment": "Alloy & Studio", "closedSprints": [ { "id": 1019, "state": "closed", "name": "2018 Sprint 07 Tooling", "startDate": "2018-03-25T21:58:00.558Z", "endDate": "2018-04-08T21:58:00.000Z", "completeDate": "2018-04-08T17:56:19.404Z", "originBoardId": 219 } ], "comment": { "comments": [ { "id": "446626", "author": { "name": "eharris", "key": "eharris", "displayName": "Ewan Harris", "active": true, "timeZone": "Europe/Dublin" }, "body": "[~topener], do you think it would be preferable to adapt https://github.com/appcelerator/alloy/pull/885 to allow behaviour as described in your last example as opposed to limiting to just $.args usage?", "updateAuthor": { "name": "eharris", "key": "eharris", "displayName": "Ewan Harris", "active": true, "timeZone": "Europe/Dublin" }, "created": "2019-03-07T21:26:21.000+0000", "updated": "2019-03-07T21:26:21.000+0000" }, { "id": "446643", "author": { "name": "topener", "key": "topener", "displayName": "Rene Pot", "active": true, "timeZone": "Europe/Berlin" }, "body": "I feel like any {{$.}} variable should be usable, though maybe that might cause issues at some point (like referencing another UI element with it as well). \r\n\r\nBut if it is possible to use anything on the {{$.}} namespace I'd prefer that over {{$.args}}", "updateAuthor": { "name": "topener", "key": "topener", "displayName": "Rene Pot", "active": true, "timeZone": "Europe/Berlin" }, "created": "2019-03-08T16:55:12.000+0000", "updated": "2019-03-08T16:55:12.000+0000" }, { "id": "446717", "author": { "name": "eharris", "key": "eharris", "displayName": "Ewan Harris", "active": true, "timeZone": "Europe/Dublin" }, "body": "I think the limitation here is that the UI element creation comes before the controller code (I've pasted an excerpt below), so when my label is set to use {{$.foo}} as it's text {{$.foo}} is not defined yet. I'm not sure whether this is achievable without having the compile process move the setting of the text (for example adding $.ELEMENTID.text = $.foo) to be after the controller defined code, we can't move the UI element creation to be after because that would break referencing UI elements from a controller, and even saying that I don't think doing that is achievable really without some special voodoo\r\n\r\n{code: title=view}\r\n\r\n\t\r\n\t\t\t\r\n\r\n{code}\r\n\r\n{code: title=tss}\r\n\"Label\": {\r\n\ttext: $.foo\r\n}\r\n{code}\r\n\r\n{code: title=controller}\r\n$.timap = require('ti.map');\r\n$.foo = 'a';\r\n\r\n$.index.open();\r\n{code}\r\n\r\n\r\n{code: title=Generated code}\r\nfunction Controller() {\r\n\r\n\trequire('/alloy/controllers/' + 'BaseController').apply(this, Array.prototype.slice.call(arguments));\r\n\tthis.__controllerPath = 'index';\r\n\tthis.args = arguments[0] || {};\r\n\r\n\tif (arguments[0]) {\r\n\t\tvar __parentSymbol = __processArg(arguments[0], '__parentSymbol');\r\n\t\tvar $model = __processArg(arguments[0], '$model');\r\n\t\tvar __itemTemplate = __processArg(arguments[0], '__itemTemplate');\r\n\t}\r\n\tvar $ = this;\r\n\tvar exports = {};\r\n\tvar __defers = {};\r\n\r\n\t$.__views.index = Ti.UI.createWindow(\r\n\t{ titleid: \"settings\", id: \"index\" });\r\n\r\n\t$.__views.index && $.addTopLevelView($.__views.index);\r\n\t$.__views.bar = Ti.UI.createLabel(\r\n\t{ text: $.foo, id: \"bar\" });\r\n\r\n\t$.__views.index.add($.__views.bar);\r\n\texports.destroy = function () {};\r\n\r\n\t_.extend($, $.__views);\r\n\r\n\t$.timap = require('ti.map');\r\n\t$.foo = 'a';\r\n\r\n\t$.index.open();\r\n\t_.extend($, exports);\r\n}\r\n{code}", "updateAuthor": { "name": "eharris", "key": "eharris", "displayName": "Ewan Harris", "active": true, "timeZone": "Europe/Dublin" }, "created": "2019-03-11T14:33:37.000+0000", "updated": "2019-03-11T14:47:38.000+0000" }, { "id": "446733", "author": { "name": "topener", "key": "topener", "displayName": "Rene Pot", "active": true, "timeZone": "Europe/Berlin" }, "body": "Oof that is a pickle... however, $.args should be known already so we should be able to support that I think? Or maybe... hoisting could be implemented for the variables being used.", "updateAuthor": { "name": "topener", "key": "topener", "displayName": "Rene Pot", "active": true, "timeZone": "Europe/Berlin" }, "created": "2019-03-11T19:09:56.000+0000", "updated": "2019-03-11T19:16:29.000+0000" }, { "id": "446734", "author": { "name": "bhouse", "key": "bhouse", "displayName": "Brenton House", "active": true, "timeZone": "America/Chicago" }, "body": "I've always added something like this to component.js which will allow the developer to create a function called __init and it would run this before most of the generated code in the controller. I tried it w/ the current proposal and it worked with $.args as well variables like $.test \r\n\r\n\r\n{noformat}\r\n__init && __init();\r\n{noformat}\r\n", "updateAuthor": { "name": "bhouse", "key": "bhouse", "displayName": "Brenton House", "active": true, "timeZone": "America/Chicago" }, "created": "2019-03-11T19:21:06.000+0000", "updated": "2019-03-11T19:21:06.000+0000" }, { "id": "446735", "author": { "name": "eharris", "key": "eharris", "displayName": "Ewan Harris", "active": true, "timeZone": "Europe/Dublin" }, "body": "$.args is fine to support as it's one of the initial things defined in the function so anything on that object is defined by the UI creation, it's possible we could hoist $.thing assignments to the [preCode|https://github.com/appcelerator/alloy/blob/784c0a7ea45510953533b1748dae0407316434b8/Alloy/template/component.js#L34] but that seems risky as it wont match the expectation of a user in how their code would execute.\r\n\r\nI think I've seen a similar proposal for what [~bhouse] is suggesting (a setup function of sorts but can't seem to find it in jira) currently. Having something like that does make sense to me, but I think given that we can't guarantee {{$.thing}} will work I think I'd prefer to just keep to {{$.args}} for now as it seems less of a foot gun and potential source of confusion to a developer.", "updateAuthor": { "name": "eharris", "key": "eharris", "displayName": "Ewan Harris", "active": true, "timeZone": "Europe/Dublin" }, "created": "2019-03-11T19:54:35.000+0000", "updated": "2019-03-11T19:54:35.000+0000" } ], "maxResults": 6, "total": 6, "startAt": 0 } } }