├── .gitignore ├── LICENSE ├── README.md ├── VERSION ├── doc └── getting_started.md ├── example ├── Framework_Verify.css ├── Framework_Verify.dart └── Framework_Verify.html ├── lib ├── puremvc.dart └── src │ ├── core │ ├── Controller.dart │ ├── Model.dart │ └── View.dart │ ├── interfaces │ ├── ICommand.dart │ ├── IController.dart │ ├── IFacade.dart │ ├── IMediator.dart │ ├── IModel.dart │ ├── INotification.dart │ ├── INotifier.dart │ ├── IObserver.dart │ ├── IProxy.dart │ └── IView.dart │ └── patterns │ ├── command │ ├── MacroCommand.dart │ └── SimpleCommand.dart │ ├── facade │ └── Facade.dart │ ├── mediator │ └── Mediator.dart │ ├── observer │ ├── Notification.dart │ ├── Notifier.dart │ └── Observer.dart │ └── proxy │ └── Proxy.dart ├── pubspec.yaml └── test ├── Test_Controller.dart ├── Test_Facade.dart ├── Test_MacroCommand.dart ├── Test_Mediator.dart ├── Test_Model.dart ├── Test_Notification.dart ├── Test_Observer.dart ├── Test_Proxy.dart ├── Test_SimpleCommand.dart ├── Test_View.dart ├── Unit_Tests.css ├── Unit_Tests.dart └── Unit_Tests.html /.gitignore: -------------------------------------------------------------------------------- 1 | pubspec.lock 2 | *.dart.js* 3 | *.dart.js.deps* 4 | *.dart.precompiled.js -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PureMVC/puremvc-dart-multicore-framework/0fdeffe9ca34bcf11350e8bf815566d47c6fd06f/LICENSE -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PureMVC/puremvc-dart-multicore-framework/0fdeffe9ca34bcf11350e8bf815566d47c6fd06f/README.md -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | PureMVC MultiCore Framework for Dart 2 | -------------------------------------------------------------------------- 3 | Release Date: 11/14/2013 4 | Platform: Google Dart 5 | Version: 2 6 | Revision: 0 7 | Minor: 6 8 | Authors: Cliff Hall 9 | -------------------------------------------------------------------------- 10 | 2.0.6 Update pubspec.yaml 11 | - environment: sdk: '>=0.8.10+6 <2.0.0' 12 | - dependencies: 13 | analyzer: '>=0.10.1 <0.11.0' 14 | browser: '>=0.9.0 <0.10.0' 15 | - dev_dependencies: 16 | unittest: '>=0.9.0 <0.10.0' 17 | Replace query() with querySelector() in Framework Test Page. 18 | Remove Unit_Tests_Config.dart and use framework enhanceed config. 19 | 20 | 2.0.5 Update pubspec.yaml 21 | - Use browser:any 22 | - Make unitest:any a dev dependency. 23 | Replace Expect with expect() in unit test classes. 24 | Modify Framework_Verify.html / Unit_Tests.html to 25 | - Reference packages/browser/dart.js. 26 | - Use innerHtml instead of innerHTML 27 | Modify Unit_Tests.html / Unit_Tests.dart 28 | - Set unittestConfiguration with the config 29 | - Reference packages/browser/dart.js. 30 | - Use innerHtml instead of innerHTML 31 | 32 | 2.0.4 Replace interface keyword with abstract class for M2 33 | Add part keywords 34 | Change Dynamic to dynamic 35 | 36 | 2.0.3 Modify pubspec.yaml again to bump the version number. Doh! 37 | 38 | 2.0.2 Modify pubspec.yaml to pull in the unit test framework from pub 39 | 40 | 2.0.1 Code cleanup to keep up with changes in Dart SDK version 0.2.2.1_r14458. 41 | Includes: 42 | - Fixed missing 'part of' directives 43 | - New library and import syntax 44 | - new getter syntax 45 | - other minor things like whitespace cleanup 46 | 47 | 2.0 Refactor to meet standards for Dart PubSpec. 48 | - library layout changes. 49 | - inclusion of unit tests (was in a separate project) 50 | - added pubspec.yaml, README.md 51 | Also, in the spirit of Dart M1, made the backward incompatible 52 | change of dropping all the MVC prefixes from the classnames 53 | in favor of using package prefix in code. 54 | 55 | 1.3 Fixed string concatenation errors in the Framework Validation Page. 56 | No changes to the framework itself. 57 | 58 | 1.2 Included .project and .children so that Dart Editor can 59 | run the framework verification page (PureMVC_Dart.dart). 60 | The need for these files should be eliminated in a future 61 | version of the editor, but they are required now. 62 | 63 | 1.1 Lots of updates and corrections to the documentation. 64 | 65 | Moved classes and interfaces into the folder locations of the 66 | reference implementation. 67 | 68 | Updated the Framework Verification Page (PureMVC_Dart.dart/html) 69 | to detect errors and give a definitive statement about the 70 | framework's operational status. 71 | 72 | Also we made the decision to disallow null multiton keys. In the 73 | original ActionScript, this is never a problem, but in the final 74 | JavaScript Dart compiles to, contention could arise if multiple 75 | apps by different vendors appear in the same page and both call 76 | Facade.getInstance() without a multiton key. 77 | 78 | 1.0 Initial version of Dart MultiCore port on PureMVC.org. 79 | -------------------------------------------------------------------------------- /doc/getting_started.md: -------------------------------------------------------------------------------- 1 | ## The PureMVC MultiCore Framework for Dart. 2 | 3 | PureMVC is a lightweight framework for creating applications based upon the classic Model-View-Controller design meta-pattern. It supports modular programming through the use of Multiton Core actors. 4 | 5 | ## General Overview 6 | 7 | * To separate coding concerns, an application (or a module in an application) is divided into three 'tiers': Model, View, and Controller. 8 | * PureMVC implements these tiers as Multiton classes which register and manage communications between the workhorse actors that operate within those tiers. 9 | * PureMVC also provides a handy frontend to the whole system called a Facade. 10 | * Since methods for message passing vary from platform to platform, PureMVC implements its own internal Observer Notification system for its actors to communicate with each other. These are not an alternative for Events. Your application's boundary classes will still interact with the DOM and services and PureMVC via Events. 11 | 12 | ## The Model Tier is handled by the Model Multiton 13 | 14 | * In the Model tier, you usually create some Value Object classes. These aren't tied to the framework and shouldn't know anything about the framework classes, they just hold data for the rest of the program to use. 15 | * The Model registers and holds instances of the Proxy class (or your subclasses) 16 | * Proxy instances are registered and retrieved from the Model by name. 17 | * Proxy classes provide access to data, local storage, and remote services. Usually a Proxy will manage a single Value Object instance or collection. For example, rather than return raw XML or JSON for the rest of the app to parse, the Proxy will convert raw data coming from sevices into typed Value Objects, easily consumed by the rest of the program. 18 | * Proxy classes do not respond to Notifications. They can be directly updated by Mediators and ICommands. 19 | * Proxy classes should not send Notification names defined elsewhere in the application. They should define their own notification names, so that the classes of the Model tier remain portable and may be unit tested or reused in other applications. 20 | 21 | ## The View Tier is handled by the View Multiton 22 | 23 | * Within the View Tier, you will usually create one or more view components, which you will write to interact directly with the Browser/DOM, listening for button presses, etc. These do not use any PureMVC framework classes and should only know about your Value Object classes in order to display, create, and modify data used by the rest of the app. They will hide the implementation of the DOM from the rest of the app, translating the button clicks and keystrokes into higher-level events that represent user intentions for initiating use-cases. 24 | * The View Multiton registers and holds instances of Mediator subclasses. 25 | * Mediators don't do heavy lifting. They are essentially switchboard operators that receive data from the rest of the app via Notification, and pass it to their view components, or receive events from their view components and in turn pass the user intention on to the rest of the app in the form of a Notification. 26 | * A Mediator will tend a particular view component, setting event listeners on it, which it handles usually by sending off Notifications to be dealt with by other Mediators and/or ICommands. 27 | * A Mediator also may assert an interest in certain Notification names, which it will be notified about if sent by other actors or itself. 28 | * A Mediator may also retrieve a Proxy and call a method on it, bypassing the Controller tier. 29 | 30 | ## The Controller Tier is handled by the Controller Multiton 31 | 32 | * Within the Controller tier, you will usually create any Notification name constants that are shared by the View and Controller tiers. Remember that Notification names sent from Proxys should be defined on the Proxys themselves for portability. 33 | * The Controller Multiton registers Notification name to ICommand mappings. 34 | * When a Notification with a registered name is sent by a Proxy, Mediator, or ICommand, the mapped ICommand is instantiated and its execute() method is called, passing in a reference to the Notification that triggered the ICommand. 35 | * The framework provides two types of ICommand implementors: MacroCommand and SimpleCommand, which you subclass to add SubCommands and business logic, respectively. 36 | * The MacroCommand executes a given set of ICommands in order, passing the Notification to each 'SubCommand' in turn. Note that a SubCommand may modify the Notification body and type and the next SubCommand will receive the modified Notification. 37 | * The SimpleCommand executes some business logic which you define. It only stays in memory until its code has been executed unless some other actor keeps a reference to it, which usually isn't desirable, but there is a formal request pattern that can be implemented that makes sense (See the O'Reilly book for info). 38 | 39 | ## The Facade Multiton provides one-stop access to Model, View, and Controller 40 | 41 | * This keeps the developer from needing to interact with all the Multitons separately. 42 | * The Facade Multiton implements all the methods of the the Model, View, and Controller Multitons and manages their creation. 43 | * Calling Facade.getInstance('someMultitonKey') for the first time, creates each of the Model, View, and Controller Multitons for that key automatically. After that, the same instance will always be returned for a given key. 44 | * All Proxy, Mediator, and ICommand instances already have a reference to their Facade instance when their onRegister() or execute() methods are called. Thus you never have to retrieve the Facade except when the Core is created. 45 | * Q: Why not just build all the MVC functionality into the Facade in the first place? A: Because it allows the developer to replace just part of the system with a custom version if they wish, leaving the other parts untouched. 46 | 47 | ## Bootstrapping your Application 48 | 49 | * Usually, your main application class will retrieve the Facade instance, register a StartupCommand, and trigger it by sending a STARTUP notification. 50 | * The StartupCommand may be a SimpleCommand or a MacroCommand that breaks the startup process into several SimpleCommands. 51 | * Regardless of implementation, the business of the StartupCommand is to prepare the Controller, Model, and View - in that order. 52 | * The Controller is prepared by registering all the Notification/ICommand mappings (or at least those needed initially). 53 | * The Model is prepared by registering all the Proxy instances needed. (Don't make service calls at this point). 54 | * The View is prepared by registering all the Mediator instances needed. 55 | * When the Mediators are registered, they usually retrieve the Proxy instances required to supply their view components with data and potentially make Proxy method calls that result in service calls. Those service calls, when they return will usually result in Notifications that trigger ICommands and/or one or more Mediators are interested in. 56 | 57 | ## MultiCore Functionality 58 | 59 | * Applications are composed of one or more 'Core's. A Core is a group of Multitons that share the same multiton key, an arbitrary, but unique name you provide (such as the name of your application). 60 | * Although most programs only need one 'Core', you can request more Facade instances using different multiton keys, in order to get multiple, isolated sets of Model, View, and Controller actors. 61 | * This allows you to do modular programming. Each 'Core' is like a separate program. It has its own group of Multitons, its own startup process, and all the workhorse classes communicate with each other through the set of Multitons they were registered with. 62 | 63 | ## Learn More About PureMVC 64 | * [Official Site](http://puremvc.org) -------------------------------------------------------------------------------- /example/Framework_Verify.css: -------------------------------------------------------------------------------- 1 | 2 | body { 3 | background-color: #F8F8F8; 4 | font-family: 'Open Sans', sans-serif; 5 | font-size: 14px; 6 | font-weight: normal; 7 | line-height: 2.0em; 8 | margin: 50px; 9 | } 10 | 11 | p { 12 | color: #333; 13 | } 14 | 15 | #container { 16 | width: 100%; 17 | height: 400px; 18 | position: relative; 19 | border: 1px solid #ccc; 20 | background-color: #fff; 21 | } 22 | 23 | #text { 24 | font-size: 16pt; 25 | text-align: left; 26 | margin-top: 10px; 27 | margin-left:25px; 28 | } 29 | -------------------------------------------------------------------------------- /example/Framework_Verify.dart: -------------------------------------------------------------------------------- 1 | import 'dart:html'; 2 | import 'package:puremvc/puremvc.dart' as mvc; 3 | 4 | class Framework_Verify { 5 | 6 | Framework_Verify() { 7 | } 8 | 9 | void verify() 10 | { 11 | String multitonKey = "Test Core"; 12 | String dataPoint1 = "Hello"; 13 | String dataPoint2 = "World"; 14 | String proxyName = "DataProxy"; 15 | List retrievedObject; 16 | String badJuju = ""; 17 | 18 | try { 19 | write (""); 50 | // Prove errors will be reported 51 | // throw "Fungers! I've got jelly in my ears!"; 52 | 53 | } on Error catch ( e ) { 54 | // Catch any error 55 | badJuju = e.toString(); 56 | 57 | } finally { 58 | // Report final status 59 | if ( badJuju.length == 0 && retrievedObject != null 60 | && retrievedObject[0] == dataPoint1 61 | && retrievedObject[1] == dataPoint2 ){ 62 | write( "

Science! PureMVC is purring like a kitten. Take her out for a spin!"); 63 | } else { 64 | write( "

Claptrap! Someone's thrown a spanner in the works."); 65 | if( badJuju.length>0 ) write( "Bad juju reported: ${badJuju}"); 66 | } 67 | } 68 | 69 | } 70 | 71 | void write(String message) { 72 | // the HTML library defines a global "document" variable 73 | document.querySelector('#text').innerHtml = "${document.querySelector('#text').innerHtml}${message}"; 74 | } 75 | } 76 | 77 | void main() { 78 | new Framework_Verify().verify(); 79 | } 80 | -------------------------------------------------------------------------------- /example/Framework_Verify.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PureMVC - Framework Verification Page 6 | 7 | 8 | 9 |

PureMVC MultiCore Framework for Dart

10 |

Framework Verification Page

11 | This page just peforms few quick checks to see that the framework is working in your environment.
12 | 13 |
14 |

15 |
16 | 17 | 18 | 20 | 21 | 22 | 23 | --------------------------------------------------------------------------------