Skip to content

Commit

Permalink
Merge pull request #18296 from emberjs/bugfix/ensure-each-in-can-iter…
Browse files Browse the repository at this point in the history
…ate-over-arbitrary-keys

[BUGFIX lts] Ensure {{each-in}} can iterate over keys with periods
  • Loading branch information
rwjblue authored Aug 23, 2019
2 parents 302c7dc + 32b4e50 commit 6fb17f5
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 3 deletions.
27 changes: 25 additions & 2 deletions packages/@ember/-internals/glimmer/lib/utils/iterable.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import { get, objectAt, tagFor, tagForProperty } from '@ember/-internals/metal';
import {
consume,
get,
isTracking,
objectAt,
tagFor,
tagForProperty,
} from '@ember/-internals/metal';
import { _contentFor } from '@ember/-internals/runtime';
import { guidFor, HAS_NATIVE_SYMBOL, isEmberArray, isProxy } from '@ember/-internals/utils';
import { EMBER_METAL_TRACKED_PROPERTIES } from '@ember/canary-features';
import { assert } from '@ember/debug';
import {
AbstractIterable,
Expand Down Expand Up @@ -127,7 +135,22 @@ class ObjectIterator extends BoundedIterator {
} else {
let values: Opaque[] = [];
for (let i = 0; i < length; i++) {
values.push(get(obj, keys[i]));
let value: any;
let key = keys[i];

value = obj[key];

// Add the tag of the returned value if it is an array, since arrays
// should always cause updates if they are consumed and then changed
if (EMBER_METAL_TRACKED_PROPERTIES && isTracking()) {
consume(tagForProperty(obj, key));

if (Array.isArray(value) || isEmberArray(value)) {
consume(tagForProperty(value, '[]'));
}
}

values.push(value);
}
return new this(keys, values, length, keyFor);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,48 @@ if (EMBER_METAL_TRACKED_PROPERTIES) {

assert.strictEqual(computeCount, 2, 'compute is called exactly 2 times');
}

'@test each-in autotracks non-tracked values correctly'() {
let obj = EmberObject.create({ value: 'bob' });

this.registerComponent('person', {
ComponentClass: Component.extend({ obj }),
template: strip`
{{#each-in this.obj as |key value|}}
{{value}}-{{key}}
{{/each-in}}
`,
});

this.render('<Person/>');

this.assertText('bob-value');

runTask(() => obj.set('value', 'sal'));

this.assertText('sal-value');
}

'@test each-in autotracks arrays acorrectly'() {
let obj = EmberObject.create({ arr: A([1]) });

this.registerComponent('person', {
ComponentClass: Component.extend({ obj }),
template: strip`
{{#each-in this.obj as |key arr|}}
{{#each arr as |v|}}{{v}}{{/each}}
{{/each-in}}
`,
});

this.render('<Person/>');

this.assertText('1');

runTask(() => obj.arr.pushObject(2));

this.assertText('12');
}
}
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,22 @@ class EachInTest extends AbstractEachInTest {

this.assertText('Empty!');
}

[`@test it can render items that contain keys with periods in them`]() {
this.makeHash({ 'period.key': 'a', 'other.period.key': 'b' });

this.render(
`<ul>{{#each-in hash as |key value|}}<li>{{key}}: {{value}}</li>{{else}}Empty!{{/each-in}}</ul>`
);

this.assertText('period.key: aother.period.key: b');

this.assertStableRerender();

this.clear();

this.assertText('Empty!');
}
}

moduleFor(
Expand Down
2 changes: 1 addition & 1 deletion packages/@ember/-internals/metal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export { Mixin, aliasMethod, mixin, observer, applyMixin } from './lib/mixin';
export { default as inject, DEBUG_INJECTION_FUNCTIONS } from './lib/injected_property';
export { tagForProperty, tagFor, markObjectAsDirty, UNKNOWN_PROPERTY_TAG } from './lib/tags';
export { default as runInTransaction, didRender, assertNotRendered } from './lib/transaction';
export { consume, Tracker, tracked, track, untrack } from './lib/tracked';
export { consume, Tracker, tracked, track, untrack, isTracking } from './lib/tracked';

export {
NAMESPACES,
Expand Down

0 comments on commit 6fb17f5

Please sign in to comment.