16. And here we are!
⦿ Open Source (BSD)
⦿ Structured
⦿ Anti-Revolutionary
⦿ Same goals as new Javascript frameworks
⦿ The goal is to not break the web
2013-04-10 Introduction to Dart 16
27. dartdoc
/// This is a single-line documentation comment.
/**
* This is a multi-line documentation comment.
* To generate the documentation:
* $ dartdoc <filename>
*/
void main() {
}
2013-04-10 Introduction to Dart 27
31. Comments
void main() {
// This is a single-line comment.
/*
* This is a
* multi-line
* comment.
*/
}
2013-04-10 Introduction to Dart 31
32. Types - Boolean
var boolean1 = true;
var boolean2 = false;
bool boolean3 = true;
bool boolean4 = false;
2013-04-10 Introduction to Dart 32
33. Types - String
String singleQuotes = 'Single quotes.';
String doubleQuotes = "Double quotes.";
// String interpolation
print('Hello $singleQuotes ${doubleQuotes.toUpperCase()}');
// Multi-line String
print('''With
triple simple quotes
I can define
a string
over multiple
lines''');
// Raw String
print(r'Hello n $singleQuotes ${doubleQuotes.toUpperCase()}');
2013-04-10 Introduction to Dart 33
34. Types - Numbers
num integer = 30;
print('integer is num: ${integer is num}'); // true
print('integer is int: ${integer is int}'); // true
print('integer is double: ${integer is double}'); // false
num intgerToo = 3.0;
print('intgerToo is num: ${intgerToo is num}'); // true
print('intgerToo is int: ${intgerToo is int}'); // true
print('intgerToo is double: ${intgerToo is double}'); // false
num doubl = 1.1;
print('doubl is num: ${doubl is num}'); // true
print('doubl is int: ${doubl is int}'); // false
print('doubl is double: ${doubl is double}'); // true
2013-04-10 Introduction to Dart 34
35. Types - Numbers
int realInt = 3;
print('realInt is num: ${realInt is num}'); // true
print('realInt is int: ${realInt is int}'); // true
print('realInt is double: ${realInt is double}'); // false
double realDouble = 1.1;
print('realDouble is num: ${realDouble is num}'); // true
print('realDouble is int: ${realDouble is int}'); // false
print('realDouble is double: ${realDouble is double}'); // true
2013-04-10 Introduction to Dart 35
36. Types – Lists
List realList = [1, true, 'String', 5.6e5];
// Creating an extendable list
List dynamicList = new List();
//dynamicList[0] = 1; // throws an exception
dynamicList.add(1);
dynamicList.add(true);
dynamicList.add('String');
dynamicList.add(5.6e5);
// Creating an empty fixed size list
// List fixedList = [null, null, null, null];
List fixedList = new List(4);
//fixedList.add(1); // throws an Exception
fixedList[0] = 1;
fixedList[1] = true;
fixedList[2] = 'String';
fixedList[3] = 5.6e5;
2013-04-10 Introduction to Dart 36
40. Loops – For in
void main() {
List<int> list = [1, 2, 3, 4, 5, 6, 7, 8, 9];
int sum = 0;
for (int element in list) {
sum += element;
}
assert(sum == 45);
}
2013-04-10 Introduction to Dart 40
41. Functions – Top-level functions
void main() {
int squaredNum = square(2);
assert(squaredNum == 4);
}
int square(int i) {
return i * i;
}
2013-04-10 Introduction to Dart 41
42. Functions – First-class functions
void main() {
List operation1 = ['+', '5', '2'];
num result1 = compute(operation1);
assert(result1 == 7);
}
num compute(List operation) {
Function operator = findOperator(operation[0]);
double left = double.parse(operation[1]);
double right = double.parse(operation[2]);
return operator(left, right);
}
2013-04-10 Introduction to Dart 42
43. Functions – typedef
void main() {
List operation1 = ['+', '5', '2'];
int result1 = computeList(operation1);
assert(result1 == 7);
}
typedef int Operator(num left, num right);
int computeList(List operation) {
Operator operator = findOperator(operation[0]);
int left = int.parse(operation[1]);
int right = int.parse(operation[2]);
return operator(left, right);
}
2013-04-10 Introduction to Dart 43
53. Classes concrètes
class User implements Validatable {
String username;
String password;
}
2013-04-10 Introduction to Dart 53
54. Classes concrètes
class User implements Validatable {
String username;
String password;
User(this.username, this.password);
}
2013-04-10 Introduction to Dart 54
55. Classes concrètes
class User implements Validatable {
String username;
String password;
User(this.username, this.password);
List<Object> valuesToValidate() {
return [username, password];
}
}
2013-04-10 Introduction to Dart 55
56. But there is more…
⦿ Mixins
⦿ Optionally typed
⦿ Top level functions
⦿ Mono process
2013-04-10 Introduction to Dart 56
57. Dart Reference API
⦿ Core ⦿ TU et Mocks
⦿ HTML ⦿ Math
⦿ Async ⦿ Logging
⦿ IO ⦿ URI
⦿ Crypto ⦿ I18N
⦿ JSON ⦿ etc.
⦿ Mirrors
⦿ UTF
2013-04-10 Introduction to Dart 57
65. The Old-Fashioned Way
void main() {
String tree = '<ul>';
for (School school in schools) {
tree += '<li>${school.schoolName}';
// Grades
tree += '</li>';
}
tree += '</ul>';
query('body').insertAdjacentHtml('afterBegin', tree);
}
2013-04-10 Introduction to Dart 65
66. The Old-Fashioned Way
var grades = school.grades;
if (grades != null) {
tree += '<ul>';
for (Grade grade in grades) {
tree += '<li>${grade.schoolGrade}';
// Students
tree += '</li>';
}
tree += '</ul>';
}
2013-04-10 Introduction to Dart 66
67. The Old-Fashioned Way
var students = grade.students;
if (students != null) {
tree += '<ul>';
for (Student student in students) {
tree +=
'<li>${student.firstname} ${student.lastname}</li>';
}
tree += '</ul>';
}
2013-04-10 Introduction to Dart 67
68. The Old-Fashioned Way
void main() { tree += '</ul>';
String tree = '<ul>'; }
for (School school in schools) { tree += '</li>';
tree += '<li>${school.schoolName}'; }
var grades = school.grades; tree += '</ul>';
if (grades != null) {
tree += '<ul>'; query('body')
.insertAdjacentHtml('afterBegin', tree);
for (Grade grade in grades) { }
tree += '<li>${grade.schoolGrade}';
var students = grade.students;
if (students != null) {
tree += '<ul>';
for (Student student in students) {
tree += '<li>${student.firstname}
${student.lastname}</li>';
}
tree += '</ul>';
}
tree += '</li>';
}
2013-04-10 Introduction to Dart 68
70. Is there a pattern here ?
var grades = school.grades;
if (grades != null) {
tree += '<ul>';
for (Grade grade in grades) {
tree += '<li>${grade.schoolGrade}';
// Students
tree += '</li>';
}
tree += '</ul>';
}
2013-04-10 Introduction to Dart 70
71. Is there a pattern here ?
var grades = school.grades;
if (grades != null) {
tree += '<ul>';
tree += '</ul>';
}
2013-04-10 Introduction to Dart 71
72. Is there a pattern here ?
var grades = school.grades;
if (grades != null) {
tree += '<ul>';
for (Grade grade in grades) {
tree += '<li>${grade.schoolGrade}';
tree += '</li>';
}
tree += '</ul>';
}
2013-04-10 Introduction to Dart 72
73. Is there a pattern here ?
var grades = school.grades;
if (grades != null) {
tree += '<ul>';
for (Grade grade in grades) {
tree += '<li>${grade.schoolGrade}';
// Do the same with children
tree += '</li>';
}
tree += '</ul>';
}
2013-04-10 Introduction to Dart 73
74. Recursive Pattern
String doSomething(/* parameters */) {
String tree = '';
var grades = school.grades;
if (grades != null) {
tree += '<ul>';
for (Grade grade in grades) {
tree += '<li>${grade.schoolGrade}';
tree += doSomething(/* parameters */);
tree += '</li>';
}
tree += '</ul>';
}
return tree;
}
2013-04-10 Introduction to Dart 74
75. Side note – Functions & sugar syntax
int length(String s) {
return s.length;
}
2013-04-10 Introduction to Dart 75
76. Side note – Functions & sugar syntax
int length(String s) { int length(String s)
return s.length; => s.length;
}
2013-04-10 Introduction to Dart 76
77. Easy use of reusable components
void main() {
final Tree tree = new Tree(...);
}
2013-04-10 Introduction to Dart 77
78. Easy use of reusable components
void main() {
final Tree tree = new Tree(...);
tree.setData(schools);
tree.addTo('body', 'afterBegin');
}
2013-04-10 Introduction to Dart 78
79. Easy use of reusable components
void main() {
final Tree tree = new Tree(
[new TreeConfig((School s) => s.schoolName,
(School s) => s.grades),
new TreeConfig((Grade g) => g.schoolGrade,
(Grade g) => g.students),
new TreeConfig((Student s) =>
'${s.firstname} ${s.lastname}')]
);
tree.setData(schools);
tree.addTo('body', 'afterBegin');
}
2013-04-10 Introduction to Dart 79
80. Easy use of reusable components
class School { class Grade {
String schoolName; String schoolGrade;
List<Grade> grades; List<Student> students;
School(this.schoolName, Grade(this.schoolGrade,
[this.grades]); [this.students]);
} }
class Student{
String firstname;
String lastname;
Student(this.firstname,
this.lastname);
}
2013-04-10 Introduction to Dart 80
81. Implementing a reusable components
typedef dynamic Accessor(dynamic data);
class TreeConfig {
Accessor _value;
Accessor _children;
TreeConfig(Accessor this._value,
[Accessor this._children]);
Accessor get value => _value;
Accessor get children => _children;
}
2013-04-10 Introduction to Dart 81
82. Implementing a reusable components
typedef dynamic Accessor(dynamic data);
class TreeConfig {
Accessor _value;
Accessor _children;
TreeConfig(Accessor this._value,
[Accessor this._children]);
Accessor get value => _value;
Accessor get children => _children;
}
2013-04-10 Introduction to Dart 82
83. Implementing a reusable components
typedef dynamic Accessor(dynamic data);
class TreeConfig {
Accessor _value;
Accessor _children;
TreeConfig(Accessor this._value,
[Accessor this._children]);
Accessor get value => _value;
Accessor get children => _children;
}
2013-04-10 Introduction to Dart 83
84. Implementing a reusable components
typedef dynamic Accessor(dynamic data);
class TreeConfig {
Accessor _value;
Accessor _children;
TreeConfig(Accessor this._value,
[Accessor this._children]);
Accessor get value => _value;
Accessor get children => _children;
}
2013-04-10 Introduction to Dart 84
85. Implementing a reusable components
class Tree {
List<TreeConfig> treeConfigs;
String tree;
Tree(this.treeConfigs);
String setData(final List data) {
// Build tree
}
void addTo(String selector,
[String where = 'afterEnd']) {
query(selector).insertAdjacentHtml(where, this.tree);
}
}
2013-04-10 Introduction to Dart 85
86. Implementing a reusable components
class Tree {
List<TreeConfig> treeConfigs;
String tree;
Tree(this.treeConfigs);
String setData(final List data) {
// Build tree
}
void addTo(String selector,
[String where = 'afterEnd']) {
query(selector).insertAdjacentHtml(where, this.tree);
}
}
2013-04-10 Introduction to Dart 86
87. Implementing a reusable components
class Tree {
List<TreeConfig> treeConfigs;
String tree;
Tree(this.treeConfigs);
String setData(final List data) {
// Build tree
}
void addTo(String selector,
[String where = 'afterEnd']) {
query(selector).insertAdjacentHtml(where, this.tree);
}
}
2013-04-10 Introduction to Dart 87
88. Implementing a reusable components
class Tree {
List<TreeConfig> treeConfigs;
String tree;
Tree(this.treeConfigs);
String setData(final List data) {
// Build tree
}
void addTo(String selector,
[String where = 'afterEnd']) {
query(selector).insertAdjacentHtml(where, this.tree);
}
}
2013-04-10 Introduction to Dart 88
89. Implementing a reusable components
class Tree {
List<TreeConfig> treeConfigs;
String tree;
Tree(this.treeConfigs);
String setData(final List data) {
// Build tree
}
void addTo(String selector,
[String where = 'afterEnd']) {
query(selector).insertAdjacentHtml(where, this.tree);
}
}
2013-04-10 Introduction to Dart 89
90. Implementing a reusable components
String buildOneLevelTree(final List data,
final List<TreeConfig> treeNodes,
[final int depth = 0]) {
String tree = '';
if (data != null && !data.isEmpty) {
}
return tree;
}
2013-04-10 Introduction to Dart 90
91. Implementing a reusable components
String buildOneLevelTree(final List data,
final List<TreeConfig> treeNodes,
[final int depth = 0]) {
String tree = '';
if (data != null && !data.isEmpty) {
final TreeConfig treeNode = treeNodes[depth];
tree += '<ul>';
for (dynamic element in data) {
}
tree += '</ul>';
}
return tree;
}
2013-04-10 Introduction to Dart 91
92. Implementing a reusable components
String buildOneLevelTree(final List data,
final List<TreeConfig> treeNodes,
[final int depth = 0]) {
String tree = '';
if (data != null && !data.isEmpty) {
final TreeConfig treeNode = treeNodes[depth];
tree += '<ul>';
for (dynamic element in data) {
tree += '<li>${treeNode.value(element)}';
tree += '</li>';
}
tree += '</ul>';
}
return tree;
}
2013-04-10 Introduction to Dart 92
93. Implementing a reusable components
String buildOneLevelTree(final List data, final List<TreeConfig> treeNodes,
[final int depth = 0]) {
String tree = '';
if (data != null && !data.isEmpty) {
final TreeConfig treeNode = treeNodes[depth];
tree += '<ul>';
for (dynamic element in data) {
tree += '<li>${treeNode.value(element)}';
if (treeNode.children != null) {
tree += buildOneLevelTree(treeNode.children(element),
treeNodes, depth + 1);
}
tree += '</li>';
}
tree += '</ul>';
}
return tree;
}
2013-04-10 Introduction to Dart 93
94. Implementing a reusable components
class Tree {
List<TreeConfig> treeConfigs;
String tree;
Tree(this.treeConfigs);
String setData(final List data) {
this.tree = buildOneLevelTree(data, this.treeConfigs);
return this.tree;
}
String buildOneLevelTree(final List data,
final List<TreeConfig> treeNodes,
[final int depth = 0]) {
// Implementation
}
void addTo(String selector,
[String where = 'afterEnd']) {
query(selector).insertAdjacentHtml(where, this.tree);
}
}
2013-04-10 Introduction to Dart 94
95. Getting ride of Strings
Element buildOneLevelTree(final List data, final List<TreeConfig> treeNodes,
[final int depth = 0]) {
Element tree; // String tree = '';
if (data != null && !data.isEmpty) {
final TreeConfig treeNode = treeNodes[depth];
tree = new UListElement(); // tree += '<ul>';
for (dynamic element in data) {
final LIElement li = new LIElement(); // <li>;
li.text = treeNode.value(element); // ${treeNode.value(element)}
if (treeNode.children != null) {
final UListElement ulChild = //
buildOneLevelTree(treeNode.children(element), treeNodes, depth + 1);
if (ulChild != null) { //
li.append(ulChild); // tree += buildOneLevelTree(...)
} //
}
tree.append(li); // tree += '<li>${treeNode.value(element)}';
}
}
return tree;
}
2013-04-10 Introduction to Dart 95
96. Getting ride of Strings
class Tree {
List<TreeConfig> treeConfigs;
Element tree; // String tree;
Tree(this.treeConfigs);
Element setData(final List data) {
this.tree = buildOneLevelTree(data, this.treeConfigs);
return this.tree;
}
Element buildOneLevelTree(final List data,
final List<TreeConfig> treeNodes,
[final int depth = 0]) {
// Implementation
}
void addTo(String selector,
[String where = 'afterEnd']) {
query(selector).insertAdjacentElement(where, this.tree);
}
}
2013-04-10 Introduction to Dart 96
98. web_ui
⦿ Based on HTML5 Web Components Spec
⦿ Syntax and uses similar to JSP tags
⦿ Template Engine – Compilation needed
⦿ Reusable components
⦿ CSS encapsulation
⦿ Data-binding
⦿ Complex for real life use-cases
⦿ Doesn’t solve layouting problems
2013-04-10 Introduction to Dart 98
115. web_ui – The application
void main() {
}
2013-04-10 Introduction to Dart 115
116. web_ui – The application
void main() {
var element = new Element.html(
'<x-click-counter id="click_counter"></x-click-counter>'
);
}
2013-04-10 Introduction to Dart 116
117. web_ui – The application
void main() {
var element = new Element.html(
'<x-click-counter id="click_counter"></x-click-counter>'
);
var counter = new CounterComponent()
..host = element
..count = 25;
}
2013-04-10 Introduction to Dart 117
118. web_ui – The application
void main() {
var element = new Element.html(
'<x-click-counter id="click_counter"></x-click-counter>'
);
var counter = new CounterComponent()
..host = element
..count = 25;
var lifecycleCaller = new ComponentItem(counter)
..create();
query('body').append(counter.host);
lifecycleCaller.insert();
}
2013-04-10 Introduction to Dart 118
119. web_ui – The application
void main() {
var element = new Element.html(
'<x-click-counter id="click_counter"></x-click-counter>'
);
var counter = new CounterComponent()
..host = element
..count = 25;
var lifecycleCaller = new ComponentItem(counter)..create();
query('body').append(counter.host);
lifecycleCaller.insert();
var button = new ButtonElement()
..text = 'Update'
..onClick.listen((e) {
counter.count = 100;
watchers.dispatch();
});
query('body').append(button);
}
2013-04-10 Introduction to Dart 119
120. A word about Layouts
2013-04-10 Introduction to Dart 120
121. A word about Layouts
2013-04-10 Introduction to Dart 121
122. A word about Layouts
2013-04-10 Introduction to Dart 122
123. A word about Layouts
2013-04-10 Introduction to Dart 123
124. A word about Layouts
2013-04-10 Introduction to Dart 124
125. A word about Layouts
builder()
..div({'id' : 'banner'})
..div({'id' : 'head'}, 'Dart Playground')
..div({'id' : 'controls'})
..span(null, 'Environment: ')
..addElement(listboxEnv)
..addElement(runButton)
..end() // controls
..end() // banner
..div({'id':'wrap'})
..addElement(e(linedTextarea.element))
..end() // wraps
..addElement(output);
2013-04-10 Introduction to Dart 125
126. A word about Layouts
builder()
..div({'id' : 'banner'})
..div({'id' : 'head'}, 'Dart Playground')
..div({'id' : 'controls'})
..span(null, 'Environment: ')
..addElement(listboxEnv)
..addElement(runButton)
..end() // controls
..end() // banner
..div({'id':'wrap'})
..addElement(e(linedTextarea.element))
..end() // wraps
..addElement(output);
2013-04-10 Introduction to Dart 126
127. A word about Layouts
builder()
..div({'id' : 'banner'})
..div({'id' : 'head'}, 'Dart Playground')
..div({'id' : 'controls'})
..span(null, 'Environment: ')
..addElement(listboxEnv)
..addElement(runButton)
..end() // controls
..end() // banner
..div({'id':'wrap'})
..addElement(e(linedTextarea.element))
..end() // wraps
..addElement(output);
2013-04-10 Introduction to Dart 127
128. A word about Layouts
builder()
..div({'id' : 'banner'})
..div({'id' : 'head'}, 'Dart Playground')
..div({'id' : 'controls'})
..span(null, 'Environment: ')
..addElement(listboxEnv)
..addElement(runButton)
..end() // controls
..end() // banner
..div({'id':'wrap'})
..addElement(e(linedTextarea.element))
..end() // wraps
..addElement(output);
2013-04-10 Introduction to Dart 128
129. The Future of Dart ?
2013-04-10 Introduction to Dart 129