4 votes

Sorties multiples dans le routeur Ember.js v2

Je commence tout juste à utiliser Ember.js et une chose qui me semble prometteuse est l'idée de points de vente multiples combinant plusieurs modèles pour produire une mise en page complexe mais modulaire.

Mais je n'arrive pas à le faire fonctionner. Il semble qu'il y avait beaucoup de questions, de réponses et d'exemples à ce sujet il y a quelques mois (mi 2012), mais dans la marche vers la 1.0, ils ont très récemment (décembre 2012/janvier 2013) réécrit le routeur vers une API "v2". Les docs sont bons dans ce qu'ils décrivent mais omettent beaucoup de contexte global, et je n'ai pas encore trouvé un seul exemple de bout en bout.

Voici ce que j'ai lu :

  • tout sous le guide du routage (à jour, mais non exhaustif)
  • Référence de l'api pour l'aide au modèle "outlet". (cette information est peut-être périmée ? Toutes les tentatives que j'ai faites pour appeler controller.connectOutlet() échoue avec Uncaught TypeError: Object <(generated animals.cats controller):ember170> has no method 'connectOutlet' .
  • annonce de API de routeur Ember.js v2 . En particulier les deux derniers commentaires (question et réponse sur plusieurs points de vente). Oui, ce résumé est marqué "Avertissement ; périmé ; pour des informations à jour, voir le guide d'acheminement". Mais le guide de routage actuel ne semble pas décrire complètement le comportement. Le site Rendu d'un modèle du guide montre comment effectuer un rendu vers différentes sorties qui existent déjà (et j'arrive à le faire fonctionner), mais je n'arrive pas à trouver comment connecter des sorties supplémentaires ou instancier des modèles supplémentaires.

Ce qui marche pour moi :

  • Configuration de routes imbriquées (enfin, de ressources imbriquées ; vous ne pouvez pas imbriquer les routes, mais vous pouvez personnaliser les routes pour les ressources imbriquées), et imbrication de modèles et de points de vente qui sont automatiquement instanciés en fonction des routes.

Ce que je n'ai pas été capable de comprendre comment accomplir :

  • Instanciez manuellement les modèles et connectez-les aux prises. Cela semble nécessaire si vous voulez utiliser plusieurs points de vente, ou si vous voulez structurer vos relations point de vente/modèle différemment de vos routes (vous trouverez un exemple de cela ci-dessous). Essentiellement, ce que j'essaie de faire est d'utiliser un modèle comme un mixin que je peux intégrer où je veux).

La chose qui semble prometteuse mais qui échoue pour moi est

  • Remplacer le contrôleur d'un itinéraire (étendre l'itinéraire à l'aide de App.WhateverRoute = Ember.Route.extend() fournir les miens setupController ) et appeler controller.connectOutlet ici. L'échec est le même que celui décrit ci-dessus ; l'objet contrôleur passé dans cette méthode n'a pas d'objet de type connectOutlet méthode.

Exemple ( ici sous forme de jsFiddle ou ci-dessous sous la forme d'un document html autonome qui intègre le CSS et les scripts et charge Ember et les dépendances à partir de liens https, de sorte que vous devriez pouvoir simplement enregistrer dans un fichier local et ouvrir dans un navigateur si vous voulez l'essayer) :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Ember.js Router Example</title>
    <style>
      .outlet {
        border: 1px solid black;
        padding: 5px;
      }
    </style>
  </head>

  <body>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
    <script src="https://raw.github.com/wycats/handlebars.js/1.0.rc.2/dist/handlebars.js"></script>
    <script src="https://raw.github.com/emberjs/ember.js/release-builds/ember-1.0.0-pre.4.js"></script>

    <script type="text/x-handlebars" data-template-name="index">
      <p>Root index template. You should not see this because we redirect App.IndexRoute elsewhere.</p>
    </script>

    <script type="text/x-handlebars" data-template-name="about">
      <p>About this demo.</p>
    </script>

    <script type="text/x-handlebars" data-template-name="guide">
      <p>Guide to this demo.</p>
    </script>

   <script type="text/x-handlebars" data-template-name="animals">
      <p>Animals. You have selected:</p>
      <div class='outlet'>{{ outlet }}</div>
    </script>

    <script type="text/x-handlebars" data-template-name="animals/index">
      <!-- you will not see this unless you disable App.AnimalsIndexRoute redirect. -->
      <p>No animal selected.</p>
    </script>

    <script type="text/x-handlebars" data-template-name="animals/cats">
      <p>Cat. I can meow. Like all animals, I
        <span class='outlet'>{{ outlet }}</span>
      </p>
    </script>

    <script type="text/x-handlebars" data-template-name="animals/dogs">
      <p>Dog. I can bark. Like all animals, I
        <span class='outlet'>{{ outlet }}</span>
      </p>
    </script>

    <script type="text/x-handlebars" data-template-name="animal_mixin">
      <p>am alive.</p>
    </script>

    <script type="text/x-handlebars" data-template-name="application">
      <div class="container">
        <p>
          Select contents for my outlet:
          {{#linkTo "index"}}/ (root){{/linkTo}}
          {{#linkTo "about"}}/about{{/linkTo}}
          {{#linkTo "guide"}}/guide{{/linkTo}}
          {{#linkTo "animals"}}/animals{{/linkTo}}
          {{#linkTo "animals.cats"}}/animals/cats{{/linkTo}}
          {{#linkTo "animals.dogs"}}/animals/dogs{{/linkTo}}
        </p>

        <div class='outlet'>
          {{ outlet }}
        </div>
      </div>
    </script>

    <script>
      App = Ember.Application.create();
      App.Router.map(function() {
        this.resource("about");
        this.resource("guide");
        this.resource("animals", function() {
          this.route("cats");
          this.route("dogs");
        })
      });
      App.IndexRoute = Ember.Route.extend({
        redirect: function() {
          this.transitionTo('about');
        }
      });
      App.AnimalsIndexRoute = Ember.Route.extend({
        redirect: function() {
          this.transitionTo('animals.cats');
        }
      });
      App.AnimalsCatsRoute = Ember.Route.extend({
        setupController: function(controller, model) {
          // BUG: this controller object has no connectOutlet method
          // (uncomment to see this yourself)
          // controller.connectOutlet('animal_mixin');
        }
      });
      App.initialize();
    </script>

</html>

Essentiellement, animal_mixin est un morceau de texte passe-partout que je veux utiliser à plusieurs reprises comme mixin, en le déposant où je veux en y plaçant un outlet et en le connectant à ce template. Je réalise que cet exemple est artificiel, parce que je pourrais le faire avec l'"héritage" fourni par la structure d'imbrication : le contenu de animal_mixin pourrait aller directement dans le modèle "animaux", et je n'aurais pas besoin de le mentionner dans animaux/chats et animaux/chiens. Ce serait bien si je le voulais dans tous les animaux, mais disons que j'ai un autre sous-routage de /animals dans lequel je ne veux pas inclure ce bout de code. Encore une fois, l'exemple est artificiel mais j'espère que la question et l'intention sont claires.

7voto

Jack Johnson Points 499

Vous pouvez utiliser plusieurs prises nommées. Voici un exemple en jsfiddle : http://jsfiddle.net/W2dE4/6/ .

<script type="text/x-handlebars" data-template-name="application">
    {{outlet header}}
    {{outlet body}}
    {{outlet navBar}}
</script>

Voir aussi cette réponse pour d'autres techniques.

events: {
    showModal: function(){
        this.render('modal', {
            into: 'index',
            outlet: 'modalOutlet',
            controller: this.controllerFor('modal')
        }); 
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X