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 avecUncaught 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 mienssetupController
) et appelercontroller.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 typeconnectOutlet
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.