Skip to content

Commit 83be482

Browse files
committed
chore(repeat): comments & tests
1 parent 6ebd642 commit 83be482

File tree

2 files changed

+73
-1
lines changed

2 files changed

+73
-1
lines changed

src/repeat.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ import {AbstractRepeater} from './abstract-repeater';
3030
@inject(BoundViewFactory, TargetInstruction, ViewSlot, ViewResources, ObserverLocator, RepeatStrategyLocator)
3131
export class Repeat extends AbstractRepeater {
3232

33+
/**
34+
* Setting this to `true` to enable legacy behavior, where a repeat would take first `matcher` binding
35+
* any where inside its view if there's no `matcher` binding on the repeated element itself.
36+
*
37+
* Default value is true to avoid breaking change
38+
* @default true
39+
*/
3340
static useInnerMatcher = true;
3441

3542
/**
@@ -272,6 +279,7 @@ export class Repeat extends AbstractRepeater {
272279
if (viewFactory) {
273280
const template = viewFactory.template;
274281
const instructions = viewFactory.instructions;
282+
// legacy behavior enabled when Repeat.useInnerMathcer === true
275283
if (Repeat.useInnerMatcher) {
276284
return extractMatcherBindingExpression(instructions);
277285
}

test/repeat.issue-378.spec.ts

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,75 @@
11
import './setup';
2-
import { StageComponent } from 'aurelia-testing';
2+
import * as AuBinding from 'aurelia-binding';
3+
import { StageComponent, ComponentTester } from 'aurelia-testing';
34
import { bootstrap } from 'aurelia-bootstrapper';
45
import { waitForFrames } from './test-utilities';
56
import { Repeat } from '../src/repeat';
67

78
// https://github.com/aurelia/templating-resources/issues/378
89
describe('repeat.issue-378.spec.ts', () => {
10+
it('extracts matcher binding corectly when matcher is on repeated element', async () => {
11+
const model = new class {
12+
products = [
13+
{ id: 0, name: 'Motherboard' },
14+
{ id: 1, name: 'CPU' },
15+
{ id: 2, name: 'Memory' }
16+
];
17+
18+
productMatcher = (a, b) => {
19+
return a.id === b.id;
20+
}
21+
22+
selectedProduct = { id: 1, name: 'CPU' };
23+
};
24+
const component: ComponentTester<Repeat> = StageComponent
25+
.withResources()
26+
.inView(`<label repeat.for="product of products" matcher.bind="productMatcher">
27+
\${product.id} - \${product.name}
28+
</label>`)
29+
.boundTo(model);
30+
31+
await component.create(bootstrap);
32+
33+
const matcherBinding = component.viewModel.matcherBinding;
34+
expect(matcherBinding).not.toBe(undefined, 'matcher binding should have existed');
35+
expect(matcherBinding instanceof (AuBinding as any).BindingExpression).toBe(true, 'it should have been a binding expression');
36+
37+
// verify that it leaves attribute intact
38+
// even when binding expression is extracted
39+
// todo: should it remove it?
40+
expect(
41+
Array.from(component['host'].querySelectorAll('label'))
42+
.filter((label: HTMLElement) => label.hasAttribute('matcher.bind')).length).toBe(3);
43+
});
44+
45+
it('does not extracts matcher binding when matcher is on repeated <template/> element', async () => {
46+
const model = new class {
47+
products = [
48+
{ id: 0, name: 'Motherboard' },
49+
{ id: 1, name: 'CPU' },
50+
{ id: 2, name: 'Memory' }
51+
];
52+
53+
productMatcher = (a, b) => {
54+
return a.id === b.id;
55+
}
56+
57+
selectedProduct = { id: 1, name: 'CPU' };
58+
};
59+
const component: ComponentTester<Repeat> = StageComponent
60+
.withResources()
61+
.inView(`<template repeat.for="product of products" matcher.bind="productMatcher">
62+
<span>\${product.id} - \${product.name}</span>
63+
</template>`)
64+
.boundTo(model);
65+
66+
await component.create(bootstrap);
67+
68+
const matcherBinding = component.viewModel.matcherBinding;
69+
expect(matcherBinding).toBe(undefined, 'matcher binding should have existed');
70+
71+
});
72+
973
it('works with <div repeat[Array] /> -->> <... matcher />', async () => {
1074
Repeat.useInnerMatcher = false;
1175
const model = new class {

0 commit comments

Comments
 (0)