2016-06-24 6 views
0

Ich möchte eine Schnittstelle in Ember, ähnlich wie Netflix ähnelt erstellen, wobei beim Klicken auf einen Filmtitel der Inhalt unter dem Plakatbild enthüllt. Meine denke, ist die eine verschachtelte Route erstellen w/Dynamic Outlet für verschachtelte Route in Ember JS

Router.map(function() { 
    this.route('movies', {path: '/' }, function() { 
    this.route('movie', { path: '/:id'}); 
    }); 
}); 

Das Problem ist, dass ich weiß nicht, wie ich eine {{outlet}} Innenseite jeder Film Komponente haben kann und sagen, die verschachtelte Route innerhalb der entsprechenden zu machen. Hat jemand etwas Ähnliches wie diese verschachtelten Routen erstellt?

enter image description here

Antwort

3

Je nachdem, ob Sie die URL sich nicht, Abfrage params wollen, oder wollen die URL ein Voll auf dem Weg zu sein, gibt es verschiedene Richtungen Sie nehmen können.

Methode 1: Keine URL Staat

Schalten movie-preview und movie-detail in Komponenten.

Sie können focus hier zu Ihrem Vorteil verwenden. Auf diese Weise wird bei Auswahl einer anderen Filmvorschau eine Komponente deaktiviert und eine andere fokussiert, ohne dass Bindungen aktualisiert werden müssen.

Im Film-preview.js

export default Component.extend({ 
    attributeBindings: ['tabindex'], 
    tabindex: 0, 
    isFocused: false, 
    movie: undefined, 

    focusIn() { 
    this.set('isFocused', true); 
    }, 

    focusOut() { 
     this.set('isFocused', false); 
    } 
}); 

In der Vorlage für Film-Vorschau, fügen wir eine bedingte.

{{#if isFocused}} 
    {{movie-detail movie=movie}} 
{{/if}} 

Aber vielleicht möchten wir diesen Zustand in der URL widerspiegeln? Beginnen wir damit, wie wir dies für Abfrageparameter tun würden.

Methode 2: Abfrage param

auf dem Controller für die Route, eine query param für selected hinzufügen.

In der Vorlage für diese Route werden wir eq (ein Helfer, eine mögliche Implementierung von denen here) verwenden isFocused einzustellen basierend darauf, ob der Film für die Vorschau ist die aktuell ausgewählte. Wir geben auch eine Aktion zur Fokuseinstellung ein.

{{#each Filme als | Film |}} {{ Film-Vorschau Film = Film IsFocused = (eq ausgewählt movie.id) select = (Aktion "selectMovie" movie.id) }} {{/ each}}

movie-preview.js wird geändert, um die Auswahl bei Klick auszulösen.

export default Component.extend({ 
    isFocused: false, 
    movie: undefined, 
    select: undefined, 

    click() { 
    this.sendAction('select'); 
    } 
}); 

Schließlich müssen wir diese Aktion in der Steuerung für diese Route behandeln.

export default Controller.extend({ 
    queryParams: ['selected'], 
    selected: undefined, 

    actions: { 
    selectMovie(movieId) { 
     this.set('selected', movieId); 
    } 
    } 
}); 

Aber vielleicht wollten wir, dass dies eine hübsche URL hat? Auch das ist einfach.

Methode 3: Recht URLs

Der erste Schritt ist Routen einzurichten verschachtelt, wie Sie zeigte.

this.route('movies', {path: '/' }, function() { 
    this.route('movie-detail', { path: '/:id'}); 
}); 

Hierfür wir brauchen eine outlet wie Sie zunächst vorgeschlagen, aber wir müssen nicht, dass von Verfahren viele Änderungen an unseren Code machen 2. Anstelle einer movie-detail Komponente, wir haben jetzt eine movie- Detailroute. Da wir die Details vorher nicht kennen mussten, werde ich das auch jetzt überspringen. Wir kümmern uns nur um die Mechanismen der "Aktivierung" der Route.

In der Vorlage für Filmvorschau ändern wir die Bedingung, um eine Steckdose zu umbrechen.

{{#if isFocused}} 
    {{outlet}} 
{{/if}} 

In der Steuerung müssen wir anstelle des Abfrageparameters einen Übergang auslösen.

export default Controller.extend({ 
    selected: undefined, 

    actions: { 
    selectMovie(movieId) { 
     this.set('selected', movieId); 

     this.transitionToRoute('movies.movie-detail', movieId); 
    }, 

    clearSelection() { 
     this.set('selected', undefined); 
     this.transitionToRoute('movies'); 
    } 
    } 
});