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

Web Component support: binding to properties #1277

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions example/bower.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "paper-example",
"version": "0.0.1",
"homepage": "https://github.com/angular/angular.dart",
"authors": [
"James deBoer <[email protected]>"
],
"description": "Paper with AngularDart",
"main": "web/index.html",
"license": "MIT",
"private": true,
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"dependencies": {
"polymer": "Polymer/polymer#~0.3.4",
"paper-elements": "Polymer/paper-elements#~0.3.4",
"core-elements": "Polymer/core-elements#~0.3.4"
}
}
1 change: 1 addition & 0 deletions example/web/bower_components
1 change: 1 addition & 0 deletions example/web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<li><a href="hello_world.html">hello_world.html</a></li>
<li><a href="todo.html">todo.html</a></li>
<li><a href="shadow_dom_components.html">shadow_dom_components.html</a></li>
<li><a href="paper_progress.html">paper_progress.html</a></li>
</ul>
</body>
</html>
13 changes: 13 additions & 0 deletions example/web/paper_progress.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import 'package:angular/angular.dart';
import 'package:angular/application_factory.dart';


main() {
var injector = applicationFactory()
.run();
var scope = injector.get(Scope);
scope.context['text'] = "Hello future";
scope.context['max'] = 20;
scope.context['curValue'] = 12;
scope.apply();
}
34 changes: 34 additions & 0 deletions example/web/paper_progress.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport"
content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">

<!-- 1. Load platform.js for polyfill support. -->
<script src="bower_components/platform/platform.js"></script>

<!-- 2. Use an HTML Import to bring in the element. -->
<link rel="import"
href="bower_components/paper-progress/paper-progress.html">
<script type="application/dart" src="paper_progress.dart"></script>
<script src="packages/browser/dart.js"></script>
<style>
div { padding: 0.25em; }
</style>
</head>
<body>
<h2>A quick demo of the Polymer paper-progress widget in an AngularDart app.</h2>
<p>The max ({{max}}) and value ({{curValue}}) properties are bound through bind-* semantics</p>

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

<div>
<paper-progress bind-max=max bind-value=curValue></paper-progress>
</div>

<p>
Change the value through an ng-model bound input box:
<input type="text" ng-model="curValue">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<label>Change the value through an ng-model bound input box: <input type="text" ng-model="curValue"></label>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

</p>
</body>
</html>
10 changes: 9 additions & 1 deletion lib/core_dom/element_binder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class ElementBinder {
}

bool get hasDirectivesOrEvents =>
_usableDirectiveRefs.isNotEmpty || onEvents.isNotEmpty;
_usableDirectiveRefs.isNotEmpty || onEvents.isNotEmpty || bindAttrs.isNotEmpty;

void _bindTwoWay(tasks, AST ast, scope, directiveScope,
controller, AST dstAST) {
Expand Down Expand Up @@ -283,6 +283,14 @@ class ElementBinder {

_link(nodeInjector, scope, nodeAttrs);

var jsNode;
bindAttrs.forEach((String prop, ast) {
if (jsNode == null) jsNode = new js.JsObject.fromBrowserObject(node);
scope.watchAST(ast, (v, _) {
jsNode[prop] = v;
});
});

if (onEvents.isNotEmpty) {
onEvents.forEach((event, value) {
view.registerEvent(EventHandler.attrNameToEventName(event));
Expand Down
62 changes: 62 additions & 0 deletions test/core_dom/web_components_spec.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
library angular.dom.web_components_spec;

import '../_specs.dart';
import 'dart:js' as js;

registerElement(String name, prototype) {
return (new js.JsObject.fromBrowserObject(document)).callMethod('registerElement',
[name, new js.JsObject.jsify({"prototype": prototype })]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Add a Map type to prototype,
  • Why do you need to {"prototype": prototype } instead of prototype ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is untyped because prototype could be a JsObject as well, although I don't use one below.

The {"prototype": prototype} comes from the registerElement spec.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The {"prototype": prototype} comes from the registerElement spec.

Thanks, didn't know about that

}



main() {
describe('WebComponent support', () {
TestBed _;

customProp(String prop, [elt]) {
if (elt == null) elt = _.rootElement;
return (new js.JsObject.fromBrowserObject(elt))[prop];
}

beforeEach((TestBed tb) {
_ = tb;
});

it('should create custom elements', () {
registerElement('tests-basic', {'prop-x': 6});

// Create a web component
_.compile('<tests-basic></tests-basic>');
expect(customProp('prop-x')).toEqual(6);
});


it('should bind to Custom Element properties', () {
registerElement('tests-bound', {'prop-y': 10});
_.compile('<tests-bound bind-prop-y=27></tests-bound>');

// Scope has not been digested yet
expect(customProp('prop-y')).toEqual(10);

_.rootScope.apply();
expect(customProp('prop-y')).toEqual(27);
});


it('should bind to a non-existent property', () {
registerElement('tests-empty', {});
_.compile('<tests-empty bind-new-prop=27></tests-empty>');
_.rootScope.apply();
expect(customProp('new-prop')).toEqual(27);
});

it('should bind to both directives and properties', () {
registerElement('tests-double', {});
_.compile('<tests-double ng-bind bind-ng-bind="\'hello\'"></tests-double>');
_.rootScope.apply();
expect(customProp('ng-bind')).toEqual("hello");
expect(_.rootElement).toHaveText('hello');
});
});
}