From f0d28c2b5518bfbfe45a357638ad1ad1a90277e1 Mon Sep 17 00:00:00 2001 From: Edward Faulkner Date: Tue, 5 May 2015 14:45:52 -0400 Subject: [PATCH] Adding positional parameter support to components A longstanding pattern is to use helpers to simulate components with positional parameters. But under Glimmer, helpers are pure functions, so this doesn't work anymore. Thankfully, we can do something even better, which is to stop wrapping components in helpers just to get positional params, and instead make components that can natively accept positional params. That's what this PR does. To use, you define your component like: ```js Ember.Component.extend({ positionalParams: ['name', 'city'] }); ``` Then you can invoke it like: ```handlebars {{my-component "Ed" "Somerville"}} ``` Which is equivalent to: ```handlebars {{my-component name="Ed" city="Somerville"}} ``` --- package.json | 2 +- .../ember-htmlbars/lib/hooks/component.js | 3 +- .../ember-htmlbars/lib/keywords/component.js | 2 +- packages/ember-htmlbars/lib/keywords/input.js | 2 +- .../ember-htmlbars/lib/keywords/textarea.js | 2 +- .../node-managers/component-node-manager.js | 8 ++++ .../integration/component_invocation_test.js | 40 +++++++++++++++++++ .../lib/keywords/link-to.js | 2 +- 8 files changed, 55 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 14da5746a07..5c1d81819bc 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "express": "^4.5.0", "github": "^0.2.3", "glob": "~4.3.2", - "htmlbars": "0.13.12", + "htmlbars": "git://github.com/ef4/htmlbars#component-params-prebuilt", "qunit-extras": "^1.3.0", "qunitjs": "^1.16.0", "route-recognizer": "0.1.5", diff --git a/packages/ember-htmlbars/lib/hooks/component.js b/packages/ember-htmlbars/lib/hooks/component.js index 3df745ce558..78662caf531 100644 --- a/packages/ember-htmlbars/lib/hooks/component.js +++ b/packages/ember-htmlbars/lib/hooks/component.js @@ -1,6 +1,6 @@ import ComponentNodeManager from "ember-htmlbars/node-managers/component-node-manager"; -export default function componentHook(renderNode, env, scope, tagName, attrs, template, visitor) { +export default function componentHook(renderNode, env, scope, tagName, params, attrs, template, visitor) { var state = renderNode.state; // Determine if this is an initial render or a re-render @@ -14,6 +14,7 @@ export default function componentHook(renderNode, env, scope, tagName, attrs, te var manager = ComponentNodeManager.create(renderNode, env, { tagName, + params, attrs, parentView, template, diff --git a/packages/ember-htmlbars/lib/keywords/component.js b/packages/ember-htmlbars/lib/keywords/component.js index 0b857cb95ff..c4947bfc0af 100644 --- a/packages/ember-htmlbars/lib/keywords/component.js +++ b/packages/ember-htmlbars/lib/keywords/component.js @@ -22,6 +22,6 @@ export default { return; } - env.hooks.component(morph, env, scope, componentPath, hash, template, visitor); + env.hooks.component(morph, env, scope, componentPath, params, hash, template, visitor); } }; diff --git a/packages/ember-htmlbars/lib/keywords/input.js b/packages/ember-htmlbars/lib/keywords/input.js index 5e66e46a5c0..be32c47e94e 100644 --- a/packages/ember-htmlbars/lib/keywords/input.js +++ b/packages/ember-htmlbars/lib/keywords/input.js @@ -13,7 +13,7 @@ export default { }, render(morph, env, scope, params, hash, template, inverse, visitor) { - env.hooks.component(morph, env, scope, morph.state.componentName, hash, template, visitor); + env.hooks.component(morph, env, scope, morph.state.componentName, params, hash, template, visitor); }, rerender(...args) { diff --git a/packages/ember-htmlbars/lib/keywords/textarea.js b/packages/ember-htmlbars/lib/keywords/textarea.js index 7b95f1e4f02..656096ae2b2 100644 --- a/packages/ember-htmlbars/lib/keywords/textarea.js +++ b/packages/ember-htmlbars/lib/keywords/textarea.js @@ -4,6 +4,6 @@ */ export default function textarea(morph, env, scope, originalParams, hash, template, inverse, visitor) { - env.hooks.component(morph, env, scope, '-text-area', hash, template, visitor); + env.hooks.component(morph, env, scope, '-text-area', originalParams, hash, template, visitor); return true; } diff --git a/packages/ember-htmlbars/lib/node-managers/component-node-manager.js b/packages/ember-htmlbars/lib/node-managers/component-node-manager.js index 1873732b7a3..01e43be1fa9 100644 --- a/packages/ember-htmlbars/lib/node-managers/component-node-manager.js +++ b/packages/ember-htmlbars/lib/node-managers/component-node-manager.js @@ -28,6 +28,7 @@ export default ComponentNodeManager; ComponentNodeManager.create = function(renderNode, env, options) { let { tagName, + params, attrs, parentView, parentScope, @@ -89,6 +90,13 @@ ComponentNodeManager.create = function(renderNode, env, options) { } renderNode.emberView = component; + + if (component.positionalParams) { + let pp = component.positionalParams; + for (let i=0; i