List of Figures

Chapter 1. Hello Dart

Figure 1.1. Dart is more than just the language. The Dart project has an entire ecosystem.

Figure 1.2. A single-page application runs in the browser, only requesting data from the server.

Figure 1.3. my_library.dart is made from greeter.dart and leavers.dart and uses another library called my_other_library.dart (which in turn is constituted from various source files).

Figure 1.4. Private elements such as fields, methods, library functions, and classes are private within a library. Privacy is indicated by an _ prefix. Users of the library can’t access private elements.

Figure 1.5. The output from clicking the button in listing 1.7

Figure 1.6. Drawing on the browser canvas

Figure 1.7. The Dart Editor, showing a simple browser application and the code-completion window

Chapter 2. “Hello World” with Dart tools

Figure 2.1. The Dart VM as a command-line tool

Figure 2.2. The Dart Editor is a lightweight version of the Eclipse tool.

Figure 2.3. Errors and warnings are shown in the Dart Editor.

Figure 2.4. The Dart VM produces output in the Editor console.

Figure 2.5. The Dart Editor Callers and Outline views

Figure 2.6. HTML links to external Dart files

Figure 2.7. Viewing the Dart Editor’s web server from Dartium

Figure 2.8. Generated dartdoc for your “Hello World” application

Figure 2.9. Setting breakpoints and debugging in the Dart Editor

Figure 2.10. Updating the status of a <div> in the browser

Figure 2.11. Dynamically adding elements

Chapter 3. Building and testing your own Dart app

Figure 3.1. The PackList application

Figure 3.2. The layout of the PackList application

Figure 3.3. The body element has a number of child elements.

Figure 3.4. The PackList UI

Figure 3.5. PackList app lets the user add an item.

Figure 3.6. Identical functions in both longhand and shorthand form, with varying levels of type information

Figure 3.7. The input text box and the items <div> can both be queried for from the document body.

Figure 3.8. The app reacts to the user clicking a packed item by adding a strikethrough.

Figure 3.9. The isPacked property adds or removes the .packed CSS class.

Figure 3.10. The code required to set up a unit test

Figure 3.11. Viewing unit test results in the browser

Chapter 4. Functional first-class functions and closures

Figure 4.1. Longhand and shorthand versions of the mix functions in Dart

Figure 4.2. Longhand functions require the return keyword to return a value, whereas shorthand functions return the result of their single-line expression automatically.

Figure 4.3. When you pass an object by reference, you can change the properties of that object but not the object itself.

Figure 4.4. The different ways that calling code can supply values for optional positional and named function parameters

Figure 4.5. The four different ways to declare a function. mix1() is in the top-level scope, and the other three are declared in a function body.

Figure 4.6. Simple local function declaration syntax

Figure 4.7. Anonymous function declaration

Figure 4.8. Named function assignment declaration

Figure 4.9. A named function declared as an argument to another function can refer to itself by name. That name isn’t available for use elsewhere.

Figure 4.10. The parameters of a function can be defined to accept another function with a specific signature.

Figure 4.11. The mix() function retains a reference to the cement variable even when mix() is passed out of the scope of the main() function that declared it.

Chapter 5. Understanding libraries and privacy

Figure 5.1. loglib functions and classes made available for external code

Figure 5.2. library is the first statement in a library.

Figure 5.3. Valid and invalid library names

Figure 5.4. The Dart Editor indicates library files in bold.

Figure 5.5. The folder structure for the loglib and PackList example

Figure 5.6. The import statement must appear before code statements.

Figure 5.7. PackList calls the top-level function in the loglib library.

Figure 5.8. The logging messages output by the Pack-List app

Figure 5.9. Multiple imported libraries can sometimes contain the same function names, so you need a mechanism to deal with these clashes.

Figure 5.10. You can declare a library prefix for use when referring to the code in an imported library.

Figure 5.11. Privacy is achieved by prefixing the class, function, property, or method name with an underscore, which allows access only from other code in the same library.

Figure 5.12. WebServerLogger can access private properties of the Logger class because they’re in the same library.

Figure 5.13. Using getters and setters to provide varying levels of field access to external users of a class

Figure 5.14. To keep your code readable and maintainable, you can extract a block of code into a private method of the same class that isn’t visible from outside the library.

Figure 5.15. loglib.dart contains a growing number of classes and functions.

Figure 5.16. The intended goal is to split the library into three files.

Figure 5.17. Splitting a single library file into separate source files

Figure 5.18. part statements must come before any other source code.

Figure 5.19. A package structure is defined by convention.

Figure 5.20. You can take an existing app and turn it into a library by adding a library statement.

Chapter 6. Constructing classes and interfaces

Figure 6.1. The implied interface is defined by the public members of the class.

Figure 6.2. A comparison of constructor syntax between Java and Dart. Dart must provide named constructors prefixed with the class name.

Figure 6.3. Static methods and properties are shared by all instances of a class.

Figure 6.4. The constructor initializer section appears after the list of constructor parameters and can be used to initialize final properties.

Chapter 7. Extending classes and interfaces

Figure 7.1. The AuthService definition from the logon_lib example

Figure 7.2. EnterpriseUser shares an “is-an” relationship with all the classes going up the hierarchy.

Figure 7.3. A child class inherits all the existing functionality from the superclass except constructors.

Figure 7.4. The current inheritance hierarchy between your interfaces and classes

Figure 7.5. Methods declared in interfaces can be implemented by child classes if the parent class is declared as abstract.

Figure 7.6. Classes automatically extend the Object base class.

Figure 7.7. All classes have an “is-an” relationship with the Object class.

Figure 7.8. Dart checks up the hierarchy for the method, which doesn’t exist. Then it checks up the hierarchy for a noSuchMethod() implementation until it finds the one declared in the base Object class.

Figure 7.9. Now that noSuchMethod() has been defined, it’s found and executed.

Figure 7.10. The equals operator from the Object class allows comparison of two instances of an object.

Figure 7.11. Illustration of where Dart implies the dynamic type, compared with the equivalent strong typing

Chapter 8. Collections of richer classes

Figure 8.1. Class hierarchy for example roles and permissions

Figure 8.2. Alice’s User object is assigned permissions by the system.

Figure 8.3. You’ll add a collection of permissions to the User class. When Alice logs on, she’ll have permissions added to that collection.

Figure 8.4. The for (... in ...) keywords allow you to iterate through each item in a list.

Figure 8.5. Collection is the core interface in Dart for dealing with collections of objects, but you need to use a concrete instance of List, Queue, or Set.

Figure 8.6. The Collection classes are generic types that contain a placeholder type E that you can replace with your own type.

Figure 8.7. A map can be defined in Dart as a list of key/value pairs.

Figure 8.8. You want to create a new value only if the key doesn’t already exist.

Figure 8.9. If you find yourself creating several similar classes that use slightly different objects but in the same way, then you could have a case for using generics.

Figure 8.10. Example of the levels of access that Alice could have in the timesheet app

Chapter 9. Asynchronous programming with callbacks and futures

Figure 9.1. The synchronous version of your Dart Lottery app will block until your code finishes executing.

Figure 9.2. The browser event loop processes events only when your Dart code isn’t executing.

Figure 9.3. The relationship between the lottery app and the lottery library

Figure 9.4. The Dart Lottery app pulls numbers after a random amount of time.

Figure 9.5. Async calls mean that control returns to the event loop as quickly as possible.

Figure 9.6. The lottery.dart file defines a getWinningNumber() function that takes a callback parameter. The app passes a callback to getWinningNumber(), which is called when a number is retrieved.

Figure 9.7. The code runs as fast as possible until the main() function finishes executing. At that point, the event loop waits for the timers to time out, calling back into the Dart code.

Figure 9.8. It’s possible to wrap an async callback API to use the Future and Completer types.

Figure 9.9. Futures.wait() allows you to wait for many futures to complete before continuing execution.

Chapter 10. Building a Dart web app

Figure 10.1. Modern web apps use the capabilities of the client to build a UI from views and data, rather than performing that processing on the server.

Figure 10.2. The DartExpense example application has list and edit views.

Figure 10.3. The main classes in the application are the models, the views, and the controller, with the constructors marked in bold.

Figure 10.4. The structure of the DartExpense app is split across multiple files referenced with the #part tag.

Figure 10.5. The app remains running and waiting for events.

Figure 10.6. The skeleton DartExpense UI, waiting for views and actions to be added

Figure 10.7. The buildUI() function uses Dart Element constructors to build the skeleton UI.

Figure 10.8. The ListView content and actions rendered with the mock data

Figure 10.9. The table created by the new generic table-generation function

Figure 10.10. The default browser event flow finds the innermost child element of the hierarchy and begins calling event-handler functions, going back up the hierarchy.

Figure 10.11. Event handlers can intercept the event on the downward capture flow instead of waiting for the default upward flow to be called.

Chapter 11. Navigating offline data

Figure 11.1. Figure 11.1 When the user clicks a button, the existing view is replaced with a new view passed from the navigate() function.

Figure 11.2. A typical URL, made up of the protocol, domain and port, and location Figure 11.3 Calling the browser’s pushState() function

Figure 11.3. Calling the browser’s pushState() function

Figure 11.4. Calling pushState() when navigating now pushes the previous location to the browser’s history.

Figure 11.5. Calling pushState() adds the state to the browser history. The browser triggers popState events when the user clicks the back and forward buttons.

Figure 11.6. You can use the Cookies view of the Chrome and Dartium developer tools to see the cookies your application has set.

Figure 11.7. Converting a map into a JSON string using JSON.stringify()

Figure 11.8. You can inspect local storage keys and values with the web browser’s developer tools.

Figure 11.9. Inspecting the amount of data stored for a particular site

Chapter 12. Communicating with other systems and languages

Figure 12.1. Integrating Dart with JavaScript

Figure 12.2. Adding a JavaScript-generated pie chart to the DartExpense app

Figure 12.3. Sending data from one VM to another requires a listener function on the receiving side.

Figure 12.4. postMessage() data is sent to all listener functions, so you need to identify that the data is meant for you.

Figure 12.5. How the DartExpense data is transformed from raw data to a pie chart

Figure 12.6. The flow from Dart to JavaScript and JavaScript to Dart

Figure 12.7. Integrating Dart with external server APIs

Figure 12.8. Using exchange rate information from a public API to convert the amount from USD to GBP

Figure 12.9. Accessing data via JSONP

Figure 12.10. Integrating Dart with the browser

Figure 12.11. The dartexpense.appcache file lists which parts of the application are cacheable and which aren’t.

Figure 12.12. When a user installs your app in Chrome, the app appears in front of the user regularly.

Figure 12.13. Developer mode provides more options for working with installable apps.

Chapter 13. Server interaction with files and HTTP

Figure 13.1. The client side of the Dart File Browser app

Figure 13.2. Dart scripts running from the command line have the same capabilities and structure as client-side scripts.

Figure 13.3. Running a simple server-side script

Figure 13.4. Passing arguments to the command line in the Dart Editor

Figure 13.5. The listDir() function uses the async exists() function and a DirectoryLister to return the list of files and folders in a directory.

Figure 13.6. Reading data from a file’s InputStream

Figure 13.7. The flow of requests between the client and server parts of the application

Figure 13.8. The output you expect from your server

Figure 13.9. The two API calls to retrieve a folder listing and file content as JSON data

Figure 13.10. The outline of ServerApp

Figure 13.11. Returning JSON data from the server API

Figure 13.12. The main actions of the client-side application request data from the server and render it in the user interface.

Figure 13.13. The outline of the ClientApp code

Chapter 14. Sending, syncing, and storing data

Figure 14.1. Dart HttpServer sends the application’s files to the browser.

Figure 14.2. Web sockets allow two-way communication between the client and server, which lets the server send data to the client without the client requesting it first.

Figure 14.3. The built-in classes you use to manage web socket connections on the client and server

Figure 14.4. As clients connect, they’re notified of the updated number of connected clients.

Figure 14.5. Sending synchronization data from one browser to other browsers via web socket connections

Figure 14.6. Sending the edited JSON

Figure 14.7. Receiving JSON expense data from a connected client

Figure 14.8. Other clients receive the JSON data and refresh.

Figure 14.9. Integrating server-side persistence with CouchDB

Figure 14.10. The CouchDB GUI web interface and the HTTP API interface

Figure 14.11. Using HttpClient to read data from HttpServer

Figure 14.12. The skeleton of the server-side CouchDbHandler class

Chapter 15. Concurrency with isolates

Figure 15.1. Skeleton of the Directory Analysis code

Figure 15.2. Adding a top-level property IsolateName, which is different in each isolate

Figure 15.3. The port.receive() handler attaches a callback function to the current isolate.

Figure 15.4. Default isolate sending data to other isolates

Figure 15.5. Default isolate waiting for the result data to be returned from the spawned isolates

Figure 15.6. A receiving isolate has a single ReceivePort but multiple SendPorts.

Figure 15.7. The SendPort from one isolate is passed into another isolate as the replyTo argument.

Figure 15.8. The Directory Analysis application will load a list of source files dynamically to analyze the list.

Figure 15.9. Dynamically loaded source files need a main() function that begins executing when loaded.

Figure 15.10. You have a list of work that can be processed concurrently.

Figure 15.11. The application spawns a fixed number of workers and sends each a folder to process.

Figure 15.12. The default isolate receives results and sends more work back to the worker isolates.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.216.151.164