2015-07-15 11 views
5

Ich bin nicht wirklich sicher, ob ich die Funktionsweise von Observablen richtig verstehe und wie man Referenzen von eingehängten Tags bekommt. Ich habe eine Komponente. Innerhalb dieser Komponente haben wir eine Komponente und eine Komponente. Der Zweck besteht darin, eine Kopplung zwischen Komponenten zu vermeiden. Aus diesem Grund möchte ich, dass meine Suchkomponente ein Ereignis auslöst, wenn eine Suche abgeschlossen ist (eine Schaltfläche wird geklickt). Dieses Ereignis sollte von der Komponente abgefangen werden, die die Sammlungsdaten basierend auf der Suche filtert.RiotJS - Wie können Ereignisse mit einem Observable-Muster zwischen Untertags übergeben werden?

Die Datei index.html mit Hilfe der Tag laden:

index.html

riot.mount(".content", "page", null); 

Die Seite wie folgt definiert ist:

page.js

<page> 
    <!-- Search tag controls --> 
    <search id="searchTag"></search> 

    <!-- Collection data to display --> 
    <collection id="collectionTag"></collection> 
</page> 

Search.js

var self = this; 
riot.observable(self); 

<!-- This function is called when the user click on the button. --> 
self.filtering = function() 
{ 
    <!-- We get data from inputs --> 
    var info = Getting data from inputs; 

    <!-- Trigger the event hoping that someone will observe it --> 
    self.trigger("filterEvent", info); 
} 

Wie kann ich die Komponente für dieses Ereignis beobachten machen:Die Komponente Skript wird wie kurz definiert?

Ich scheint es, dass ich in der Lage sein sollte, Referenzen von Such Tag und Sammlung Tag in dem page.js zu bekommen. Dadurch konnte ich die Ereignisse wie folgen an:

searchComponent = riot.mount('search'); 
collectionComponent = riot.mount('collection'); 

searchComponent.on('filterEvent', function() 
{ 
    <!-- Trigger function to filter collection data --> 
    collectionComponent.trigger('filterData'); 
}); 

Im Moment kann ich es nicht so funktioniert.

Zum Zeitpunkt der Ausführung sind searchComponent und collectionComponent nicht definiert.

ich auch versucht Referenzen dieser Komponente erhalten durch die Verwendung this.searchTag und this.collectionTag statt sie zu Montage aber zum Zeitpunkt der Code ausgeführt wird, haben die Komponenten nicht montiert worden ist und so nicht, daß ich ihnen einen Verweis erhalten.

Irgendwelche Ideen, damit es funktioniert?

+2

Beachten Sie, dass Sie nicht brauchen, als auch riot.observable (Selbst-) auf Krawall Tags zu nennen, wie Sie dies nicht tun müssen sie mounten, wenn sie Kinderelemente eines anderen Riot-Tags sind. Sie müssen nur das Root-Tag mounten. – gius

Antwort

2

Erstens verstehe ich Ihre Dateistruktur nicht!

An deiner Stelle würde ich Dateinamen ändern:

page.js -> page.tag

Search.js -> Suche.tag

Und ich sehe nicht Ihre Suche Tag in search.js Code.


Also nicht ich Ihre Sammlung Tag-Datei sehen ...

Sind Sie sicher, dass dies eine diesen Code verwenden? riot.observable({self|this}); Weil er es ist, der ein Ereignis erhalten wird.

Für mich wenn ich Riot.js (2.2.2) in meinem Browser, wenn ich searchComponent = riot.mount('search'); searchComponent wird

Aber mit diesem Code nicht definiert werden, können Sie Ihre monted Tag Referenz speichern:

var searchComponent ={}; 
riot.compile(function() { 
    searchComponent = riot.mount('search')[0]; 
}); 
13

Versuchen Sie, eine gemeinsame Observable an beide Tags zu übergeben.

var sharedObservable = riot.observable(); 

riot.mount('search', {observable: sharedObservable}); // the second argument will be used as opts 
riot.mount('collection', {observable: sharedObservable}); 

Und dann in den Tags, es einfach zu verwenden:

this.opts.observable.trigger('myEvent'); 

this.opts.observable.on('myEvent', function() { ... }); 

EDIT: Oder noch besser, da Ihre search und collection Tags sind Kind-Tags von anderen riot-Tag (page) (und damit Sie müssen sie auch nicht manuell mounten). Sie können das übergeordnete Element als gemeinsame Observable verwenden. Also einfach auslösen oder Ereignisse in Ihrem Kind-Tags wie folgt behandeln:

this.parent.trigger('myEvent'); 

this.parent.on('myEvent', function() { ... }); 
+0

+1 für die parent.trigger() -Methode. Ist es möglich, während der Auslösung des Ereignisses zusätzliche Daten zu senden? Beispielsweise muss die Suchleiste möglicherweise den "Suchabfragetext" senden. Wie können diese zusätzlichen Daten von einem Kind-Tag in einem anderen Kind-Tag zugänglich gemacht werden? –

+1

@ GopalakrishnaPalem natürlich können Sie. Fügen Sie einfach Parameter zur Triggerfunktion hinzu und sie werden an die Handler-Funktion übergeben. Siehe http://riotjs.com/api/observable/#a-nametrigger-argsa-eltriggerevent-arg1--argn – gius

12

durch die von @gius gegebene Antwort inspiriert, das ist jetzt meine bevorzugte Methode für die Ereignisse in RiotJS von einem Tag zum anderen zu senden .. und es ist toll zum arbeiten! Der Unterschied zu @gius Ansatz ist, dass, wenn Sie viele verschachtelte Tags verwenden, die Weitergabe eines gemeinsamen Observable an jedes Tag zu kurz kommt, weil Sie es immer wieder an jedes Kind-Tag übergeben (oder aufrufen müssen) aus dem Kind Tags mit chaotisch this.parent Anrufe).

Wenn Sie ein einfaches Mixin definieren, wie dieses (unten), das einfach ein Observable definiert, bedeutet dies, dass Sie es jetzt in einem beliebigen Tag teilen können.

var SharedMixin = { 
observable: riot.observable() 
}; 

Fügen Sie diese Zeile in Ihre Tags ..

this.mixin(SharedMixin); 

Und nun, jeden Tag, das die obige Zeile enthält Ereignisse wie ..

this.observable.trigger('event_of_mine'); 

.or Ereignisse empfangen abfeuern kann wie dieser ..

this.observable.on('event_of_mine',doSomeStuff()); 

Siehe meine Arbeit jsfiddle hier http://jsfiddle.net/3b32yqb1/5/.

+0

Versuchen Sie RiotControl https://github.com/jimsparkman/RiotControl - es bringt Ihren Ansatz noch weiter – gius

+0

Ah, Aufstandsbekämpfung. Ich habe das benutzt, aber ich habe mich damit gestritten, was mich auf diese Seite geführt hat. Beim Versuch, Ereignisse nur an Tags zu senden (nicht an einen Store), wurden die Ereignisse zweimal ausgelöst. Dieses Problem ist Gegenstand dieser gtihub-Probleme https://github.com/jimsparkman/RiotControl/issues/9 und https://github.com/jimsparkman/RiotControl/issues/7. Nachdem ich diese gelesen hatte, lehnte ich ab, dass meine Ereignisse tatsächlich einmal pro Store feuern (Huh!). Außerdem ist RiotControl eine Art Flux (einseitiger Datenfluss unter Verwendung von Stores). Für mich ist die einfache Weitergabe eines Observable eine sehr flexible Möglichkeit für die Kommunikation von Tags. –

0

Eine andere Möglichkeit ist die Verwendung von globalen Observablen, was wahrscheinlich nicht immer der beste Weg ist. Wir verwenden die eingebauten Bedingungen von Riot, um Tags zu installieren, wenn bestimmte Bedingungen erfüllt sind, anstatt sie direkt über JS zu mounten. Dies bedeutet, dass Tags unabhängig voneinander sind.

Zum Beispiel könnte eine einzelne Observable verwendet werden, um die gesamte Kommunikation zu verwalten.Dies ist kein eigenständiges Beispiel, es ist nur eine Technik zu demonstrieren.

Zum Beispiel in einer Ebene JS-Datei wie main.js:

var myApp = riot.observable(); 

Eine Tag-Datei kann ein Update auslösen.

var self = this; 
message = self.message; 
myApp.trigger('NewMessage', message); 

Eine beliebige Anzahl von anderen Tag-Dateien für ein Update hören:

myApp.on('NewMessage', function(message) { 
    // Do something with the new message "message" 
    console.log('Message received: ' + message); 
});