Skip to content

Commit 332dba9

Browse files
committed
fix(compiler): support filters in attribute expressions
Fixes dart-archive#571
1 parent f5668e3 commit 332dba9

File tree

4 files changed

+51
-10
lines changed

4 files changed

+51
-10
lines changed

lib/core_dom/block_factory.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ class BlockFactory {
9999
assert((timerId = _perf.startTimer('ng.block.link.setUp', _html(node))) != false);
100100
Injector nodeInjector;
101101
Scope scope = parentInjector.get(Scope);
102+
FilterMap filters = parentInjector.get(FilterMap);
102103
Map<Type, _ComponentFactory> fctrs;
103104
var nodeAttrs = node is dom.Element ? new NodeAttrs(node) : null;
104105
ElementProbe probe;
@@ -199,7 +200,7 @@ class BlockFactory {
199200
}
200201
if (nodeAttrs == null) nodeAttrs = new _AnchorAttrs(ref);
201202
for(var map in ref.mappings) {
202-
map(nodeAttrs, scope, controller);
203+
map(nodeAttrs, scope, controller, filters);
203204
}
204205
if (controller is NgAttachAware) {
205206
var removeWatcher;

lib/core_dom/common.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ List<dom.Node> cloneElements(elements) {
44
return elements.map((el) => el.clone(true)).toList();
55
}
66

7-
typedef ApplyMapping(NodeAttrs attrs, Scope scope, Object dst);
7+
typedef ApplyMapping(NodeAttrs attrs, Scope scope, Object dst, FilterMap filters);
88

99
class DirectiveRef {
1010
final dom.Node element;

lib/core_dom/compiler.dart

+8-8
Original file line numberDiff line numberDiff line change
@@ -146,17 +146,17 @@ class Compiler {
146146
ApplyMapping mappingFn;
147147
switch (mode) {
148148
case '@':
149-
mappingFn = (NodeAttrs attrs, Scope scope, Object dst) {
149+
mappingFn = (NodeAttrs attrs, Scope scope, Object dst, FilterMap filters) {
150150
attrs.observe(attrName, (value) => dstPathFn.assign(dst, value));
151151
};
152152
break;
153153
case '<=>':
154-
mappingFn = (NodeAttrs attrs, Scope scope, Object dst) {
154+
mappingFn = (NodeAttrs attrs, Scope scope, Object dst, FilterMap filters) {
155155
if (attrs[attrName] == null) return;
156156
Expression attrExprFn = _parser(attrs[attrName]);
157157
var shadowValue = null;
158158
scope.$watch(
159-
() => attrExprFn.eval(scope),
159+
() => attrExprFn.eval(scope, filters),
160160
(v) => dstPathFn.assign(dst, shadowValue = v),
161161
attrs[attrName]);
162162
if (attrExprFn.isAssignable) {
@@ -173,22 +173,22 @@ class Compiler {
173173
};
174174
break;
175175
case '=>':
176-
mappingFn = (NodeAttrs attrs, Scope scope, Object dst) {
176+
mappingFn = (NodeAttrs attrs, Scope scope, Object dst, FilterMap filters) {
177177
if (attrs[attrName] == null) return;
178178
Expression attrExprFn = _parser(attrs[attrName]);
179179
scope.$watch(
180-
() => attrExprFn.eval(scope),
180+
() => attrExprFn.eval(scope, filters),
181181
(v) => dstPathFn.assign(dst, v),
182182
attrs[attrName]);
183183
};
184184
break;
185185
case '=>!':
186-
mappingFn = (NodeAttrs attrs, Scope scope, Object dst) {
186+
mappingFn = (NodeAttrs attrs, Scope scope, Object dst, FilterMap filters) {
187187
if (attrs[attrName] == null) return;
188188
Expression attrExprFn = _parser(attrs[attrName]);
189189
var stopWatching;
190190
stopWatching = scope.$watch(
191-
() => attrExprFn.eval(scope),
191+
() => attrExprFn.eval(scope, filters),
192192
(value) {
193193
if (dstPathFn.assign(dst, value) != null) {
194194
stopWatching();
@@ -198,7 +198,7 @@ class Compiler {
198198
};
199199
break;
200200
case '&':
201-
mappingFn = (NodeAttrs attrs, Scope scope, Object dst) {
201+
mappingFn = (NodeAttrs attrs, Scope scope, Object dst, FilterMap filters) {
202202
dstPathFn.assign(dst, _parser(attrs[attrName]).bind(scope, ScopeLocals.wrapper));
203203
};
204204
break;

test/core_dom/compiler_spec.dart

+40
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ main() => describe('dte.compiler', () {
180180
module.type(LogComponent);
181181
module.type(AttachDetachComponent);
182182
module.type(SimpleComponent);
183+
module.type(ExprAttrComponent);
184+
module.type(HelloFilter);
183185
}));
184186

185187
it('should select on element', async(inject((NgZone zone) {
@@ -364,6 +366,16 @@ main() => describe('dte.compiler', () {
364366
}).toThrow("Unknown mapping 'foo\' for attribute 'attr'.");
365367
})));
366368

369+
it('should support filters in attribute expressions', async(inject(() {
370+
var element = $(r'''<expr-attr-component expr="'Misko' | hello" one-way="'James' | hello" once="'Chirayu' | hello"></expr-attr-component>''');
371+
$compile(element, directives)(injector, element);
372+
ExprAttrComponent component = $rootScope['exprAttrComponent'];
373+
$rootScope.$digest();
374+
expect(component.expr).toEqual('Hello, Misko!');
375+
expect(component.oneWay).toEqual('Hello, James!');
376+
expect(component.exprOnce).toEqual('Hello, Chirayu!');
377+
})));
378+
367379
it('should error on non-asignable-mapping', async(inject(() {
368380
expect(() {
369381
var element = $(r'<div><non-assignable-mapping></non-assignable-mapping</div>');
@@ -787,3 +799,31 @@ class MissingSelector {}
787799
@NgComponent(selector: 'buttonbar button')
788800
class InvalidSelector {}
789801

802+
@NgFilter(name:'hello')
803+
class HelloFilter {
804+
call(String str) {
805+
return 'Hello, $str!';
806+
}
807+
}
808+
809+
810+
@NgComponent(
811+
selector: 'expr-attr-component',
812+
template: r'<content></content>',
813+
publishAs: 'ctrl',
814+
map: const {
815+
'expr': '<=>expr',
816+
'one-way': '=>oneWay',
817+
'once': '=>!exprOnce'
818+
}
819+
)
820+
class ExprAttrComponent {
821+
var expr;
822+
var oneWay;
823+
var exprOnce;
824+
825+
ExprAttrComponent(Scope scope) {
826+
scope.$root.exprAttrComponent = this;
827+
}
828+
}
829+

0 commit comments

Comments
 (0)