Browser/NodeJS -reaktive Programmierung und datengesteuerte DOM -Manipulation mit modularen Komponenten.
Dokumentation: http://milojs.github.io/milo/
npm install milojs
oder
bower install milo
npm install
npm install -g grunt-cli
grunt test
So führen Sie alle Tests aus, einschließlich Browser -Tests:
grunt tests
index.html
< html >
< head >
< title > Binding example </ title >
< script src =" milo.bundle.js " > </ script >
< script src =" index.js " > </ script >
</ head >
< body >
< input type =" text " ml-bind =" [Data]:myField " >
< div ml-bind =" [Data]:myCurrentValue " > </ div >
< button ml-bind =" [Events]:myTestButton " >
Test
</ button >
< div >
< span ml-bind =" :myTestValue " > </ span >
</ div >
< div >
< h2 > I am connected: </ h2 >
< span ml-bind =" [Data]:myTestValue2 " > </ span >
</ div >
</ body >
</ html >index.js
// run when DOM is ready
milo ( function ( ) {
// create and bind components with milo.binder
var scope = milo . binder ( ) ;
// attach subscriber to data change event via data facet
// of myField component
scope . myField . data . on ( '' , function ( msg , data ) {
scope . myCurrentValue . data . set ( data . newValue ) ;
// alternatively:
// scope.myCurrentValue.el.innerHTML = data.newValue;
} ) ;
// attach subscriber to click event via events facet
// of myTestButton component
scope . myTestButton . events . on ( 'click' , function ( msg , event ) {
scope . myTestValue . el . innerHTML = scope . myField . data . value ( ) ;
} ) ;
// connect two components directly via their data facets
// using milo.minder
milo . minder ( scope . myField . data , '->' , scope . myTestValue2 . data ) ;
} ) ; Milo verwendet das Check -Modul ( milo.util.check - Forked vom Checkpaket des Meteor -Frameworks) für die Laufzeitprüfung von Parametertypen. Es wird dringend empfohlen, diese Überprüfungen in der Produktion mit: milo.config({ check: false }) auszuschalten.
Abhängig von Ihrer Anwendung kann es die Leistung mehr als zweimal verbessern.
Einführung in die Bindung
Einführung in die Datenfacette
Einführung in Messenger
Einführung in Modelle
Einführung in Minder
Einführung in Listen
Artikel über das Erstellen von Milo -Rollen Ihres eigenen Frameworks für Tuts+
Das fortgeschrittenere Beispiel ist die Todos -App im Ordner "ToMVC".
cd $MILO_FOLDER
npm link
cd $MY_PROJECT
rm -R -f -d node_modules/milojs
npm link milojs # link milo to your current project to use with browserify
cd $MILO_FOLDER
grunt # rebuild milo bundle every time you change any .js fileAußerdem können Sie in Ihrem Projekt Grunzen einrichten, um es wieder aufzubauen, wenn sich Milo Bundle ändert.
Bitte stellen Sie sicher, dass Sie grunt tests durchführen, bevor Sie sich verpflichten (nicht nur grunt test , der automatisch von Travisci durchgeführt wird), sondern alle Tests, einschließlich Browser -Tests.
Obwohl Milo als ein Bündel verpackt ist, hat es eine sehr modulare Struktur. Es besteht aus mehreren unabhängigen Modulen, die zusammen oder separat verwendet werden können und die gemeinsame Anwendungsaufgaben vereinfachen, anstatt eine bestimmte Anwendungsstruktur zu erstellen.
Einige Module in Milo können nur im Browser (Komponente, Komponentfacet, Milo.binder), einige sowohl im Browser als auch in NodeJs (Messenger und seinen zugehörigen Klassen, Modell, Stecker, Milo.minder) verwendet werden.
Milo selbst verwendet Browserify, um das Paketpaket zu packen, aber jedes Modulsystem kann in einer App verwendet werden, die Milo verwendet - Milo schlägt keine Anwendungsstruktur vor.
Die Komponente ist so konzipiert, dass die Verwaltung von DOM vereinfacht wird. Die Komponente wird an ein bestimmtes DOM -Element angehängt. Das Anbringen mehrerer Komponenten an dasselbe DOM -Element ist normalerweise ein Anwendungsfehler (oder ein MILO).
Komponenten ermöglichen eine sehr einfache Erstellung von Unterklassen, die als Sammlung konfigurierter "Facetten" definiert sind. Siehe beispielsweise die Definition der MLSelect UI -Komponente.
Es gibt eine Komponentenvorlage, um die Erstellung Ihrer eigenen Komponenten zu vereinfachen.
Siehe Komponentendokumentation.
ComponentFacet ist eine Basisklasse, von denen Unterklassen, welche Gruppenmethoden mit Verhaltensweisen von Komponenten zusammenhängen.
Sie müssen selten eine Facette instanziieren - wenn eine Komponente erstellt wird
In Milo sind die folgenden Facetten definiert:
Es gibt eine Komponenten -Facetten -Vorlage, um die Erstellung Ihrer eigenen Facetten zu vereinfachen. Alle Facetten von Komponenten sollten Unterklassen von KomponentFacet sein.
Instanzen Ihrer Komponenten werden normalerweise automatisch erstellt, wenn Sie milo.binder basierend auf Informationen zu Komponentenklassen, Facetten und Komponentennamen im ml-bind -Attribut (können über Milo.config geändert werden) aufgerufen.
Um Ihre Komponenten für den Milo zur Verfügung zu stellen, sollten ihre Klassen in der Komponentenregistrierung (milo.registry.comPonents) registriert werden. Wenn Sie neue Facetten definieren, sollten ihre Klassen auch registriert werden (in milo.registry.facets).
Da die Registrierung von Komponenten und Facettenklassen normalerweise im selben Modul (Datei) stattfindet, das die Klasse definiert, müssen Sie dieses Modul ausführen. Wenn Sie BrooSerify für die Modulverwaltung verwenden, reicht es aus:
require('my_component');
In jedem anderen Modul, das ausgeführt oder erforderlich ist.
Milo liefert interne Messaging -Klassen, die auch für Anwendungsanforderungen verwendet werden können. Alle Facetten in Milo haben eine Instanz von Messenger, die ihnen beigefügt ist und die für die Facette spezifische Messaging -API definiert, in den meisten Fällen eine Verbindung zu einer externen Quelle (normalerweise DOM -Ereignisse).
Messenger -Instanzen verwenden Instanzen von MessageSource -Unterklassen, um eine Verbindung zu externen Quellen und Instanzen von MessengerAPI -Unterklassen herzustellen, um interne Nachrichten auf höherer Ebene zu erstellen und Nachrichtendaten zu transformieren. Diese Architektur ermöglicht das Erstellen einer erweiterten Funktionalität in nur wenigen Codezeilen.
Siehe Messenger -Dokumentation.
Milo definiert das Modell, um einen sicheren Zugriff auf die Daten zu ermöglichen, ohne sich Sorgen zu machen, ob die Daten festgelegt wurden (es wird nie ausgelöst, wenn Sie auf Daten zugreifen, wenn Sie Eigenschaften von undefinierten Objekten erhalten) und die Möglichkeit zu ermöglichen, Datenänderungen zu abonnieren, ähnlich wie das experimentelle Objekt.
Die Verwendung von Modell erfordert diese APIs nicht und ermöglicht im Gegensatz zu diesen APIs Änderungen zu den Eigenschaften Ihrer Modelle in jeder Tiefe ab.
Siehe Modelldemo und Modelldokumentation.
Milo definiert diese Klasse so, dass die reaktive Verbindung zwischen Objekten verwaltet wird, die Datennachrichten -API implementieren. Beide Fälle von Datenfacetten und Modellen sind solche Objekte.
Sie können Ein- oder Zwei-Wege-Verbindungen erstellen, die Tiefe Ihrer Datenstrukturen definieren, die Sie beobachten möchten, diese Verbindungen ausschalten, z. B. wenn Sie viele Modelländerungen vornehmen möchten, ohne DOM-Updates zu verursachen.
Diese Verbindungen haben keinen Overhead, wenn Sie Daten in der Schleife wie angularjs vergleichen, und verursachen keine Leistungsverschlechterung, wenn viele verbundene Objekte existieren.
Sehr bald unterstützt die Steckerinstanzen die Strukturübersetzung, die es ermöglicht, reaktive Verbindungen zwischen Modellen mit festen Strukturen und Dombäumen mit flexiblen Strukturen zu erzeugen.
Eine oder mehrere reaktive Verbindungen können mit milo.minder erstellt werden.
Siehe Connector -Dokumentation.
domready -Ereignis definiert und das Routing von Nachrichten zwischen IFrames vereinfacht (siehe Frame Facette).Milo Name wurde aufgrund von Milo Minderbinder ausgewählt, einem Kriegsprofiteer von Catch 22. Nachdem er mit der Verwaltung von Messoperationen begonnen hatte, erweiterte er sie zu einem profitablen Handelsunternehmen, das alle mit allem verband, und in diesem Milo und alle anderen "hat" eine Aktie ".
Milo Das Framework verfügt über den Modulbinder , der DOM-Elemente an Komponenten bindet (über das spezielle ML-Bind-Attribut), und den Modul- Minder , mit dem Live-reaktive Verbindungen zwischen verschiedenen Datenquellen hergestellt werden können (Modell- und Datenfact von Komponenten sind solche Datenquellen).
Zufälligerweise kann Milo als Akronym von Mail online gelesen werden.
Alle Frameworks, die wir in die Hände legen konnten, waren entweder zu primitiv, um uns zu viel Code zu schreiben (JQuery, Backbone) oder zu begrenzend, mit genügend Magie, um eine einfache Anwendung zu erstellen, aber mit begrenzter Kontrolle über eine präzise Funktion des Gerüsts (Angular, Ext).
Was wir immer wollten, war ein Framework, der es zulässt
Wir konnten ein solches Framework nicht finden, also begannen wir, Milo parallel zur Anwendung zu entwickeln, die sie verwendet.
### Prototyp basieren der Vererbung
Milo stützt sich auf JavaScript -Prototypen, um Framework -Blöcke zu erstellen.
JavaScript ist eine sehr dynamische Sprache. Es ermöglicht Schreibfunktionen, die Klassen erstellen ( Component.createComponentClass ), die ein Kompositionsmuster implementieren konnten, bei dem jede Komponentenklasse als Sammlung vordefinierter Blöcke (Facetten) mit Konfiguration einer Facetten erstellt wird, die für eine konstruierte Klasse spezifisch ist (es hat eine gewisse Ähnlichkeit zu Ausmaß, obwohl sie nicht aus Blöcken erstellt wurden).
Mit JavaScript können Konstruktorfunktionen erstellt werden, die Funktionen erstellen, die eine sehr ausdrucksstarke Syntax für Modellobjekte sowie eine "Kompilierung" von Modellzugriffspfaden in Funktionen in Funktionen ermöglichen.
Die Komponentenklasse basiert auf einer abstrakten FacetedObject -Klasse, die auf jede Domäne angewendet werden kann, in der Objekte über die Sammlung von Facetten dargestellt werden können (eine Facette ist ein Objekt einer bestimmten Klasse, sie enthält eigene Konfiguration, Daten und Methoden).
In gewisser Weise ist das Facettenmuster eine Inversion des Adaptermusters - während letztere eine Klasse/Methoden finden, die eine spezifische Funktionalität aufweist, wird Facettenobjekt einfach so konstruiert, dass diese Funktionen auftreten. Auf diese Weise ist es möglich, eine praktisch unbegrenzte Anzahl von Komponentenklassen mit einer sehr begrenzten Anzahl von Bausteinen zu erstellen, ohne eine hohe Hierarchie von Klassen zu haben - die meisten Komponenten erben direkt aus der Komponentenklasse.
Gleichzeitig unterstützt Milo den Vererbungsmechanismus, wenn die Unterklasse denjenigen, die sich bereits in der Superklasse befinden, Facetten hinzufügen und die Konfiguration ererbter Facetten neu definieren können.
Wir verwenden auch Mixin -Muster, aber Mixin in Milo wird als separates Objekt implementiert, das auf der Eigenschaft des Host -Objekts gespeichert ist und bei Bedarf Proxy -Methoden für das Host -Objekt erstellen kann. Klassen Messenger, MessageSource und DataSource sind Unterklassen der Mixin -Abstract -Klasse.
Komponenten und Facetten registrieren sich in Registern, mit denen sie vermeiden können, dass sie von einem Modul von einem Modul verlangt werden. Es verhindert kreisförmige Abhängigkeiten zwischen Modulen.
Die Abhängigkeiten von Milo sind Proto , eine Objektmanipulationsbibliothek und ein Punkt , ein Templating -Engine (beide sind im Milo -Bündel enthalten).
Wir verwenden keine DOM -Traversal -Bibliothek, weil:
Stattdessen können Milo -Komponenten eine DOM -Facette haben, die mehrere Komfortfunktionen enthält, um DOM -Elemente zu manipulieren, und es gibt milo.util.dom - eine ähnliche Sammlung von Funktionen, die ohne Komponenten verwendet werden können.
Milo verwendet Bibliotheksproto mit einer erwachsenen Sammlung von Nutzfunktionen für die Manipulation von Objekten, Prototypen, Arrays, Funktionen und Saiten. Weitere Dokumentationen und Gründe für die Entscheidung, keine Bibliotheken von Drittanbietern zu verwenden, finden Sie in seinem Repository.
Es ist zusammen mit Milo gebündelt und alle seine Funktionen sind als Eigenschaften _ Objekts erhältlich. Sie müssen es nicht separat laden.
http://opensource.org/licenses/bsd-2-clause
Siehe Veröffentlichungen