Singular #gwtcreate +DanielKurka @dankurka AngularJs http://upload.wikimedia.org/wikipedia/commons/2/2a/Boxing_Tournament_in_Aid_of_King_George's_Fund_For_Sailors_at_the_Royal_Naval_Air_Station,_Henstridge,_Somerset,_July_1945_A29806.jpg The good http://upload.wikimedia.org/wikipedia/commons/0/02/Nice_view_(3201807289).jpg Developer productivity Express intend Eliminate boilerplate Application structure Testing as a first class citizen How does Angular do it? A Todo application JavaScript function TodoCtrl($scope) { $scope.todos = [ {text:'Learn AngularJS', done:false}, {text: 'Build an app', done:false} ]; $scope.addTodo = function () { $scope.todos.push({text:$scope.formTodoText, done:false}); $scope.formTodoText = ''; }; ! $scope.clearCompleted = function () { $scope.todos = _.filter($scope.todos, function(todo){ return !todo.done; }); }; } JavaScript function TodoCtrl($scope) { $scope.todos = [ {text:'Learn AngularJS', done:false}, {text: 'Build an app', done:false} ]; $scope.addTodo = function () { $scope.todos.push({text:$scope.formTodoText, done:false}); $scope.formTodoText = ''; }; ! $scope.clearCompleted = function () { $scope.todos = _.filter($scope.todos, function(todo){ return !todo.done; }); }; } JavaScript function TodoCtrl($scope) { $scope.todos = [ {text:'Learn AngularJS', done:false}, {text: 'Build an app', done:false} ]; $scope.addTodo = function () { $scope.todos.push({text:$scope.formTodoText, done:false}); $scope.formTodoText = ''; }; ! $scope.clearCompleted = function () { $scope.todos = _.filter($scope.todos, function(todo){ return !todo.done; }); }; } JavaScript function TodoCtrl($scope) { $scope.todos = [ {text:'Learn AngularJS', done:false}, {text: 'Build an app', done:false} ]; $scope.addTodo = function () { $scope.todos.push({text:$scope.formTodoText, done:false}); $scope.formTodoText = ''; }; ! $scope.clearCompleted = function () { $scope.todos = _.filter($scope.todos, function(todo){ return !todo.done; }); }; } HTML <div ng-controller="TodoCtrl"> <ul> <li ng-repeat="todo in todos"> <input type="checkbox" ng-model="todo.done"/> <span class="done-{{todo.done}}">{{todo.text}}</span> </li> </ul> <form> <input type="text" ng-model="formTodoText" /> <button ng-click="addTodo()"><h2>Add</h2></button> </form> <button ng-click="clearCompleted()">Clear completed</button> </div> HTML <div ng-controller="TodoCtrl"> <ul> <li ng-repeat="todo in todos"> <input type="checkbox" ng-model="todo.done"/> <span class="done-{{todo.done}}">{{todo.text}}</span> </li> </ul> <form> <input type="text" ng-model="formTodoText" /> <button ng-click="addTodo()"><h2>Add</h2></button> </form> <button ng-click="clearCompleted()">Clear completed</button> </div> HTML <div ng-controller="TodoCtrl"> <ul> <li ng-repeat="todo in todos"> <input type="checkbox" ng-model="todo.done"/> <span class="done-{{todo.done}}">{{todo.text}}</span> </li> </ul> <form> <input type="text" ng-model="formTodoText" /> <button ng-click="addTodo()"><h2>Add</h2></button> </form> <button ng-click="clearCompleted()">Clear completed</button> </div> HTML <div ng-controller="TodoCtrl"> <ul> <li ng-repeat="todo in todos"> <input type="checkbox" ng-model="todo.done"/> <span class="done-{{todo.done}}">{{todo.text}}</span> </li> </ul> <form> <input type="text" ng-model="formTodoText" /> <button ng-click="addTodo()"><h2>Add</h2></button> </form> <button ng-click="clearCompleted()">Clear completed</button> </div> HTML <div ng-controller="TodoCtrl"> <ul> <li ng-repeat="todo in todos"> <input type="checkbox" ng-model="todo.done"/> <span class="done-{{todo.done}}">{{todo.text}}</span> </li> </ul> <form> <input type="text" ng-model="formTodoText" /> <button ng-click="addTodo()"><h2>Add</h2></button> </form> <button ng-click="clearCompleted()">Clear completed</button> </div> HTML <div ng-controller="TodoCtrl"> <ul> <li ng-repeat="todo in todos"> <input type="checkbox" ng-model="todo.done"/> <span class="done-{{todo.done}}">{{todo.text}}</span> </li> </ul> <form> <input type="text" ng-model="formTodoText" /> <button ng-click="addTodo()"><h2>Add</h2></button> </form> <button ng-click="clearCompleted()">Clear completed</button> </div> The bad Performance Multiple problems Scanning the DOM at runtime to find directives Dirty checking loop Not optimizable by compilers These cause serious performance issues! Get the good without the bad? What do we need to do? Parse templates at compile time Resolve directives at compile time Understand the scope sufficient enough to not require dirty checking Make downloads smaller Remember GWT: Smallest and Fastest in class? Singular Angular in Java Static typing helps us understand the scope No dirty checking! Will scale to big applications & run efficiently on mobile Java gives us great tools support Java gives us best in class output size Demo Already 4x smaller http://www.gamerzines.com/wp-content/uploads/2014/03/morpheus-chair.jpg Initial rendering already 20x faster http://www.gamerzines.com/wp-content/uploads/2014/03/morpheus-chair.jpg Runtime already 5x faster http://www.gamerzines.com/wp-content/uploads/2014/03/morpheus-chair.jpg But there is more Application structure Model Model Controller Model View Controller MVC Presentation state Model Rendering logic Presentation state Model View Screen Rendering logic Presentation state Model View Screen Rendering logic Presentation state Model Controller UI Event Handling logic View Screen Rendering logic Presentation state Model Controller UI Event Handling logic View Screen Rendering logic Presentation state Model Controller UI Event Handling logic View Screen Rendering logic Presentation state Model Controller UI Event Handling logic View Screen Rendering logic Presentation state Model Controller UI Event Handling logic View Screen Angular Model View Controller Controller Model Application logic Presentation state Event Handling View Rendering logic Screen Controller Model Application logic Presentation state Event Handling View Rendering logic Screen Controller Model Application logic Presentation state Event Handling View Rendering logic Screen Controller Model Application logic Presentation state Event Handling View Rendering logic Screen Controller Model Application logic Presentation state Event Handling Directives Rendering logic Screen Sweet spot: Cross platform apps Platform specific template files: ! Web: HTML Android: xml files iOS: UiBuilder Optionally: Customize template per platform Freedom to change the UI Share controllers across platforms Keeps application logic in sync Easy way to break out Demo Singular on Android Cross platform APIs HTTP Interface HTTP Interface Web HTTP Interface Android Web HTTP Interface Android Web iOS Dependency injection to wire it up HTTP, Sockets HTTP, Sockets Storage, FileSystem HTTP, Sockets Storage, FileSystem Location, Camera, Media HTTP, Sockets Storage, FileSystem Location, Camera, Media Notifications, Status Existing work Phonegap Break out? http://upload.wikimedia.org/wikipedia/commons/1/1e/Dog_in_animal_shelter_in_Washington,_Iowa.jpg Web @NGApp(template = "hello.html") public interface HelloApp extends NGBinder<Element> { } Definition Web @NGApp(template = "hello.html") public interface HelloApp extends NGBinder<Element> { } NGBinder<Element> binder = new HelloAppBinder(); binder.start(Document.get().getBody()); Definition Usage Android @NGApp(os = OS.ANDROID, template = "hello.xml") public interface HelloApp extends NGBinder<View>{ } Definition Android @NGApp(os = OS.ANDROID, template = "hello.xml") public interface HelloApp extends NGBinder<View>{ } Definition public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ! LinearLayout l = (LinearLayout) findViewById(R.id.root); ! NgBinder<View> binder = new HelloAppBinder(getBaseContext()); binder.start(l); } } Example usage Android @NGApp(os = OS.ANDROID, template = "hello.xml") public interface HelloApp extends NGBinder<View>{ } Definition public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ! LinearLayout l = (LinearLayout) findViewById(R.id.root); ! NgBinder<View> binder = new HelloAppBinder(getBaseContext()); binder.start(l); } } Example usage Android @NGApp(os = OS.ANDROID, template = "hello.xml") public interface HelloApp extends NGBinder<View>{ } Definition public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ! LinearLayout l = (LinearLayout) findViewById(R.id.root); ! NgBinder<View> binder = new HelloAppBinder(getBaseContext()); binder.start(l); } } Example usage Framework public interface NGBinder<T> { Registration start(T parent); } Base interface public interface Registration { void cancel(); } Registration Integrate it into any existing app Just pass the parent Also: Mark nodes as external Easy migration path for existing GWT apps Testing in Singular Controller Model Application logic Presentation state Event Handling View Rendering logic Screen Controller Model Application logic Presentation state pure Java No more GWTTestcase Works with any Java mocking framework Java @Test public void addTodo() { NGTodoScope scope = new NGTodoScope(); TodoController todoController = new TodoController(scope); ! assertEquals(2, scope.getTodos().size()); assertEquals("Learn singular", scope.getTodos().get(0).getText()); assertEquals("Build app", scope.getTodos().get(1).getText()); ! scope.setFormTodoText("foobar"); todoController.addTodo(); ! assertEquals(3, scope.getTodos().size()); assertEquals("foobar", scope.getTodos().get(2).getText()); } Java @Test public void addTodo() { NGTodoScope scope = new NGTodoScope(); TodoController todoController = new TodoController(scope); ! assertEquals(2, scope.getTodos().size()); assertEquals("Learn singular", scope.getTodos().get(0).getText()); assertEquals("Build app", scope.getTodos().get(1).getText()); ! scope.setFormTodoText("foobar"); todoController.addTodo(); ! assertEquals(3, scope.getTodos().size()); assertEquals("foobar", scope.getTodos().get(2).getText()); } Java @Test public void addTodo() { NGTodoScope scope = new NGTodoScope(); TodoController todoController = new TodoController(scope); ! assertEquals(2, scope.getTodos().size()); assertEquals("Learn singular", scope.getTodos().get(0).getText()); assertEquals("Build app", scope.getTodos().get(1).getText()); ! scope.setFormTodoText("foobar"); todoController.addTodo(); ! assertEquals(3, scope.getTodos().size()); assertEquals("foobar", scope.getTodos().get(2).getText()); } Java @Test public void addTodo() { NGTodoScope scope = new NGTodoScope(); TodoController todoController = new TodoController(scope); ! assertEquals(2, scope.getTodos().size()); assertEquals("Learn singular", scope.getTodos().get(0).getText()); assertEquals("Build app", scope.getTodos().get(1).getText()); ! scope.setFormTodoText("foobar"); todoController.addTodo(); ! assertEquals(3, scope.getTodos().size()); assertEquals("foobar", scope.getTodos().get(2).getText()); } Sum http://upload.wikimedia.org/wikipedia/commons/6/65/Cute_beagle_puppy_lilly.jpg AngularJs http://upload.wikimedia.org/wikipedia/commons/2/2a/Boxing_Tournament_in_Aid_of_King_George's_Fund_For_Sailors_at_the_Royal_Naval_Air_Station,_Henstridge,_Somerset,_July_1945_A29806.jpg The good http://upload.wikimedia.org/wikipedia/commons/0/02/Nice_view_(3201807289).jpg Developer productivity Testing as a first class citizen The bad Performance Singular Angular in Java No dirty checking! Will scale to big applications & run efficiently on mobile Already 4x smaller http://www.gamerzines.com/wp-content/uploads/2014/03/morpheus-chair.jpg Initial rendering already 20x faster http://www.gamerzines.com/wp-content/uploads/2014/03/morpheus-chair.jpg Runtime already 5x faster http://www.gamerzines.com/wp-content/uploads/2014/03/morpheus-chair.jpg Controller Model Application logic Presentation state Event Handling Directives Rendering logic Screen Android Web iOS Platform specific template files: ! Web: HTML Android: xml files iOS: UiBuilder Freedom to change the UI Share controllers across platforms Singular on Android Singular on iOS Thank you! +DanielKurka @dankurka #gwt Any questions? +DanielKurka @dankurka #gwt
© Copyright 2024