Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit c53dc77

Browse files
committed
feat(element binder): Bind to Web Component properties
Closes #1277
1 parent 1ef882c commit c53dc77

File tree

3 files changed

+76
-3
lines changed

3 files changed

+76
-3
lines changed

example/web/paper_progress.html

+5-2
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,18 @@
1212
href="bower_components/paper-progress/paper-progress.html">
1313
<script type="application/dart" src="paper_progress.dart"></script>
1414
<script src="packages/browser/dart.js"></script>
15+
<style>
16+
div { padding: 0.25em; }
17+
</style>
1518
</head>
1619
<body>
1720
<h2>A quick demo of the Polymer paper-progress widget in an AngularDart app.</h2>
18-
<p>The max ({{max}}) and value ({{curValue}}) properties are bound through attribute intropolation</p>
21+
<p>The max ({{max}}) and value ({{curValue}}) properties are bound through bind-* semantics</p>
1922

2023
<p>Text from Angular: <b>{{text}}</b></p>
2124

2225
<div>
23-
<paper-progress max={{max}} value={{curValue}}></paper-progress>
26+
<paper-progress bind-max=max bind-value=curValue></paper-progress>
2427
</div>
2528

2629
<p>

lib/core_dom/element_binder.dart

+9-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class ElementBinder {
6262
}
6363

6464
bool get hasDirectivesOrEvents =>
65-
_usableDirectiveRefs.isNotEmpty || onEvents.isNotEmpty;
65+
_usableDirectiveRefs.isNotEmpty || onEvents.isNotEmpty || bindAttrs.isNotEmpty;
6666

6767
void _bindTwoWay(tasks, AST ast, scope, directiveScope,
6868
controller, AST dstAST) {
@@ -283,6 +283,14 @@ class ElementBinder {
283283

284284
_link(nodeInjector, scope, nodeAttrs);
285285

286+
var jsNode;
287+
bindAttrs.forEach((String prop, ast) {
288+
if (jsNode == null) jsNode = new js.JsObject.fromBrowserObject(node);
289+
scope.watchAST(ast, (v, _) {
290+
jsNode[prop] = v;
291+
});
292+
});
293+
286294
if (onEvents.isNotEmpty) {
287295
onEvents.forEach((event, value) {
288296
view.registerEvent(EventHandler.attrNameToEventName(event));
+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
library angular.dom.web_components_spec;
2+
3+
import '../_specs.dart';
4+
import 'dart:js' as js;
5+
6+
registerElement(String name, prototype) {
7+
return (new js.JsObject.fromBrowserObject(document)).callMethod('registerElement',
8+
[name, new js.JsObject.jsify({"prototype": prototype })]);
9+
}
10+
11+
12+
13+
main() {
14+
describe('WebComponent support', () {
15+
TestBed _;
16+
17+
customProp(String prop, [elt]) {
18+
if (elt == null) elt = _.rootElement;
19+
return (new js.JsObject.fromBrowserObject(elt))[prop];
20+
}
21+
22+
beforeEach((TestBed tb) {
23+
_ = tb;
24+
});
25+
26+
it('should create custom elements', () {
27+
registerElement('tests-basic', {'prop-x': 6});
28+
29+
// Create a web component
30+
_.compile('<tests-basic></tests-basic>');
31+
expect(customProp('prop-x')).toEqual(6);
32+
});
33+
34+
35+
it('should bind to Custom Element properties', () {
36+
registerElement('tests-bound', {'prop-y': 10});
37+
_.compile('<tests-bound bind-prop-y=27></tests-bound>');
38+
39+
// Scope has not been digested yet
40+
expect(customProp('prop-y')).toEqual(10);
41+
42+
_.rootScope.apply();
43+
expect(customProp('prop-y')).toEqual(27);
44+
});
45+
46+
47+
it('should bind to a non-existent property', () {
48+
registerElement('tests-empty', {});
49+
_.compile('<tests-empty bind-new-prop=27></tests-empty>');
50+
_.rootScope.apply();
51+
expect(customProp('new-prop')).toEqual(27);
52+
});
53+
54+
it('should bind to both directives and properties', () {
55+
registerElement('tests-double', {});
56+
_.compile('<tests-double ng-bind bind-ng-bind="\'hello\'"></tests-double>');
57+
_.rootScope.apply();
58+
expect(customProp('ng-bind')).toEqual("hello");
59+
expect(_.rootElement).toHaveText('hello');
60+
});
61+
});
62+
}

0 commit comments

Comments
 (0)