Skip to content

Commit

Permalink
[BUGFIX beta] Allows for an arbitrary # of positional parameters
Browse files Browse the repository at this point in the history
When the `positionalParams` property on a component is a string, the
positional parameters passed to the component will be an array that is
bound to that attribute, as per requested by @rwjblue here:
#11028 (comment)
  • Loading branch information
danmcclain committed May 19, 2015
1 parent 76f5665 commit 2d128db
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { MUTABLE_CELL } from "ember-views/compat/attrs-proxy";
import SafeString from "htmlbars-util/safe-string";
import { instrument } from "ember-htmlbars/system/instrumentation-support";
import EmberComponent from "ember-views/views/component";
import Stream from 'ember-metal/streams/stream';
import { readArray } from 'ember-metal/streams/utils';

// In theory this should come through the env, but it should
// be safe to import this until we make the hook system public
Expand Down Expand Up @@ -89,10 +91,26 @@ function extractPositionalParams(renderNode, component, params, attrs) {
// if the component is rendered via {{component}} helper, the first
// element of `params` is the name of the component, so we need to
// skip that when the positional parameters are constructed
let paramsStartIndex = renderNode.state.isComponentHelper ? 1 : 0;
let pp = component.positionalParams;
for (let i=0; i<pp.length; i++) {
attrs[pp[i]] = params[paramsStartIndex + i];
const paramsStartIndex = renderNode.state.isComponentHelper ? 1 : 0;
const positionalParams = component.positionalParams;
const isNamed = typeof positionalParams === 'string';
let paramsStream;

if (isNamed) {
paramsStream = new Stream(() => {
return readArray(params.slice(paramsStartIndex));
}, 'params');

attrs[positionalParams] = paramsStream;
}

for (let i=0; i < positionalParams.length; i++) {
let param = params[paramsStartIndex + i];
if (isNamed) {
paramsStream.addDependency(param);
} else {
attrs[positionalParams[i]] = param;
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import ComponentLookup from 'ember-views/component_lookup';
import Component from "ember-views/views/component";
import { runAppend, runDestroy } from "ember-runtime/tests/utils";
import { get } from "ember-metal/property_get";
import { set } from "ember-metal/property_set";
import run from "ember-metal/run_loop";

var registry, container, view;
Expand Down Expand Up @@ -258,7 +259,7 @@ if (Ember.FEATURES.isEnabled('ember-views-component-block-info')) {
});
}

QUnit.test('static positional parameters', function() {
QUnit.test('static named positional parameters', function() {
registry.register('template:components/sample-component', compile('{{attrs.name}}{{attrs.age}}'));
registry.register('component:sample-component', Component.extend({
positionalParams: ['name', 'age']
Expand All @@ -274,7 +275,7 @@ QUnit.test('static positional parameters', function() {
equal(jQuery('#qunit-fixture').text(), 'Quint4');
});

QUnit.test('dynamic positional parameters', function() {
QUnit.test('dynamic named positional parameters', function() {
registry.register('template:components/sample-component', compile('{{attrs.name}}{{attrs.age}}'));
registry.register('component:sample-component', Component.extend({
positionalParams: ['name', 'age']
Expand All @@ -292,13 +293,58 @@ QUnit.test('dynamic positional parameters', function() {
runAppend(view);
equal(jQuery('#qunit-fixture').text(), 'Quint4');
run(function() {
Ember.set(view.context, 'myName', 'Edward');
Ember.set(view.context, 'myAge', '5');
set(view.context, 'myName', 'Edward');
set(view.context, 'myAge', '5');
});

equal(jQuery('#qunit-fixture').text(), 'Edward5');
});

QUnit.test('static arbitrary number of positional parameters', function() {
registry.register('template:components/sample-component', compile('{{#each attrs.names as |name|}}{{name}}{{/each}}'));
registry.register('component:sample-component', Component.extend({
positionalParams: 'names'
}));

view = EmberView.extend({
layout: compile('{{sample-component "Foo" 4 "Bar" id="args-3"}}{{sample-component "Foo" 4 "Bar" 5 "Baz" id="args-5"}}{{component "sample-component" "Foo" 4 "Bar" 5 "Baz" id="helper"}}'),
container: container
}).create();

runAppend(view);

equal(view.$('#args-3').text(), 'Foo4Bar');
equal(view.$('#args-5').text(), 'Foo4Bar5Baz');
equal(view.$('#helper').text(), 'Foo4Bar5Baz');
});

QUnit.test('dynamic arbitrary number of positional parameters', function() {
registry.register('template:components/sample-component', compile('{{#each attrs.names as |name|}}{{name}}{{/each}}'));
registry.register('component:sample-component', Component.extend({
positionalParams: 'names'
}));

view = EmberView.extend({
layout: compile('{{sample-component user1 user2 id="direct"}}{{component "sample-component" user1 user2 id="helper"}}'),
container: container,
context: {
user1: 'Foo',
user2: 4
}
}).create();

runAppend(view);
equal(view.$('#direct').text(), 'Foo4');
equal(view.$('#helper').text(), 'Foo4');
run(function() {
set(view.context, 'user1', 'Bar');
set(view.context, 'user2', '5');
});

equal(view.$('#direct').text(), 'Bar5');
equal(view.$('#helper').text(), 'Bar5');
});

QUnit.test('moduleName is available on _renderNode when a layout is present', function() {
expect(1);

Expand Down Expand Up @@ -360,8 +406,8 @@ if (Ember.FEATURES.isEnabled('ember-htmlbars-component-helper')) {
runAppend(view);
equal(jQuery('#qunit-fixture').text(), 'Quint4');
run(function() {
Ember.set(view.context, 'myName', 'Edward');
Ember.set(view.context, 'myAge', '5');
set(view.context, 'myName', 'Edward');
set(view.context, 'myAge', '5');
});

equal(jQuery('#qunit-fixture').text(), 'Edward5');
Expand All @@ -382,7 +428,7 @@ QUnit.test('yield to inverse', function() {
runAppend(view);
equal(jQuery('#qunit-fixture').text(), 'Yes:Hello42');
run(function() {
Ember.set(view.context, 'activated', false);
set(view.context, 'activated', false);
});

equal(jQuery('#qunit-fixture').text(), 'No:Goodbye');
Expand Down

0 comments on commit 2d128db

Please sign in to comment.