J'ai un contrôleur chargé de communiquer avec une API pour mettre à jour les propriétés d'un utilisateur, nom, e-mail, etc. Chaque utilisateur a un 'id'
qui est transmis par le serveur lorsque la page de profil est consultée.
Je voudrais transmettre cette valeur au contrôleur AngularJS afin qu'il sache quel est le point d'entrée de l'API pour l'utilisateur actuel. J'ai essayé de transmettre la valeur ng-controller
. Par exemple:
function UserCtrl(id, $scope, $filter) {
$scope.connection = $resource('api.com/user/' + id)
et dans le HTML
<body ng-controller="UserCtrl({% id %})">
où {% id %}
imprimer l'identifiant envoyé par le serveur. mais je reçois des erreurs.
Quelle est la bonne façon de transmettre une valeur à un contrôleur lors de sa création?
javascript
angularjs
nickponline
la source
la source
Réponses:
Remarques:
Cette réponse est ancienne. Ce n'est qu'une preuve de concept sur la façon dont le résultat souhaité peut être atteint. Cependant, ce n'est peut-être pas la meilleure solution selon certains commentaires ci-dessous. Je n'ai aucune documentation pour soutenir ou rejeter l'approche suivante. Veuillez vous référer à certains des commentaires ci-dessous pour une discussion plus approfondie sur ce sujet.
Réponse originale:
J'ai répondu à Oui, vous pouvez absolument le faire à l'aide d'
ng-init
une simple fonction d'initialisation.En voici l'exemple sur plunker
HTML
Javascript
la source
The only appropriate use of ngInit for aliasing special properties of ngRepeat, as seen in the demo below. Besides this case, you should use controllers rather than ngInit to initialize values on a scope.
ng-init
se produireJe suis très en retard et je n'ai aucune idée si c'est une bonne idée, mais vous pouvez inclure l'
$attrs
injectable dans la fonction contrôleur permettant au contrôleur d'être initialisé en utilisant des "arguments" fournis sur un élément, par exempleEncore une fois, aucune idée si c'est une bonne idée, mais cela semble fonctionner et c'est une autre alternative.
la source
ng-init
- si vous essayez de vous lier à une valeur d'étendue, il exécute déjà la fonction de contrôleur avant qu'il neng-init
se produise - voir plnkr.co/edit/donCm6FRBSX9oENXh9WJ?p=previewCela fonctionne également.
Javascript:
Html:
la source
La vue ne doit pas dicter la configuration
Dans Angular, le modèle ne doit jamais dicter la configuration, ce qui est intrinsèquement ce que les gens souhaitent lorsqu'ils souhaitent passer des arguments aux contrôleurs à partir d'un fichier de modèle. Cela devient une pente glissante. Si les paramètres de configuration sont codés en dur dans les modèles (par exemple, par une directive ou un attribut d'argument de contrôleur), vous ne pouvez plus réutiliser ce modèle pour autre chose que pour cette utilisation unique. Bientôt, vous voudrez réutiliser ce modèle, mais avec une configuration différente et maintenant, pour ce faire, vous devrez soit prétraiter les modèles pour injecter des variables avant de les passer en angulaire, soit utiliser des directives massives pour cracher géant. des blocs de HTML afin que vous réutilisiez tout le code HTML du contrôleur, à l'exception du div wrapper et de ses arguments. Pour les petits projets, ce n'est pas grave. Pour quelque chose de grand (ce que l'angulaire excelle), ça devient très vite laid.
L'alternative: les modules
Ce type de configuration est ce que les modules ont été conçus pour gérer. Dans de nombreux didacticiels angulaires, les gens ont un seul module pour l'ensemble de leur application, mais en réalité, le système est conçu et prend entièrement en charge de nombreux petits modules qui enveloppent de petits morceaux de l'application totale. Idéalement, les contrôleurs, modules, etc. devraient être déclarés dans des fichiers séparés et assemblés en morceaux spécifiques réutilisables. Lorsque votre application est conçue de cette façon, vous obtenez beaucoup de réutilisation en plus des arguments de contrôleur faciles.
L'exemple ci-dessous a 2 modules, réutilisant le même contrôleur, mais chacun avec ses propres paramètres de configuration. Les paramètres de configuration sont transmis via l'injection de dépendances à l'aide de
module.value
. Cela adhère à la méthode angulaire, car nous avons les éléments suivants: injection de dépendance du constructeur, code de contrôleur réutilisable, modèles de contrôleur réutilisables (le div du contrôleur pourrait facilement être inclus avec ng-include), système facilement testable par unité sans HTML, et enfin réutilisable modules comme véhicule pour assembler les pièces.Voici un exemple:
Voyez-le en action: jsFiddle .
la source
Comme @akonsu et Nigel Findlater suggèrent, vous pouvez lire l'URL où URL est
index.html#/user/:id
avec$routeParams.id
et de l' utiliser à l' intérieur du contrôleur.votre application:
le service des ressources
le controlle
puis,
elm
est accessible dans la vue en fonction duid
.la source
Si ce
ng-init
n'est pas pour passer des objets$scope
, vous pouvez toujours écrire votre propre directive. Voici donc ce que j'ai obtenu:http://jsfiddle.net/goliney/89bLj/
Javasript:
Html:
Mais mon approche ne peut que modifier des objets, qui sont déjà définis au niveau du contrôleur.
la source
Il semble que la meilleure solution pour vous soit en fait une directive. Cela vous permet d'avoir toujours votre contrôleur, mais de lui définir des propriétés personnalisées.
Utilisez-le si vous avez besoin d'accéder aux variables dans la portée d'encapsulation:
Utilisez ceci si vous n'avez pas besoin d'accéder aux variables dans la portée d'encapsulation:
la source
J'ai trouvé des variables de passage de $ routeProvider utiles.
Par exemple, vous utilisez un contrôleur MyController pour plusieurs écrans, en passant à l'intérieur une variable très importante "mySuperConstant".
Utilisez cette structure simple:
la source
Vous pouvez le faire lors de la configuration des itinéraires, par exemple
Et plus tard, utilisez-le comme
Voici donc quand nous avons configuré l'itinéraire que nous avons envoyé: itemType et récupérez-le plus tard à partir de $ routeParams.
la source
Il existe une autre façon de transmettre des paramètres à un contrôleur en injectant $ routeParams dans votre contrôleur, puis en utilisant les paramètres url décrits ici Quelle est la façon la plus concise de lire les paramètres de requête dans AngularJS?
la source
Cette question est ancienne mais j'ai eu du mal pendant longtemps à essayer d'obtenir une réponse à ce problème qui répondrait à mes besoins et ne l'a pas facilement trouvée. Je crois que ma solution suivante est bien meilleure que celle actuellement acceptée, peut-être parce que angular a ajouté des fonctionnalités depuis que cette question a été posée à l'origine.
Réponse courte, l'utilisation de la méthode Module.value vous permet de transmettre des données à un constructeur de contrôleur.
Voir mon plongeur ici
Je crée un objet modèle, puis je l'associe au contrôleur du module, en le référençant avec le nom «modèle»
HTML / JS
Le constructeur de mon contrôleur accepte alors un paramètre avec le même identifiant «modèle» auquel il peut alors accéder.
Manette
Remarques:
J'utilise l'initialisation manuelle du bootstrap , ce qui me permet d'initialiser mon modèle avant de l'envoyer en angulaire. Cela fonctionne beaucoup mieux avec le code existant, car vous pouvez attendre de configurer vos données pertinentes et de compiler le sous-ensemble angulaire de votre application à la demande lorsque vous le souhaitez.
Dans le plunker, j'ai ajouté un bouton pour alerter les valeurs de l'objet modèle initialement défini en javascript et passé à angular, juste pour confirmer que angular fait vraiment référence à l'objet modèle, plutôt que de le copier et de travailler avec une copie.
Sur cette ligne:
Je passe l'objet MyController dans la fonction Module.controller, plutôt que de le déclarer en tant que fonction inline. Je pense que cela nous permet de définir beaucoup plus clairement notre objet contrôleur, mais la documentation angulaire a tendance à le faire en ligne, donc j'ai pensé qu'elle méritait des éclaircissements.
J'utilise la syntaxe "controller as" et j'assigne des valeurs à la propriété "this" de MyController, plutôt que d'utiliser la variable "$ scope". Je pense que cela fonctionnerait aussi bien en utilisant $ scope, l'affectation du contrôleur ressemblerait alors à ceci:
et le constructeur du contrôleur aurait une signature comme celle-ci:
Si pour une raison quelconque vous vouliez, vous pouvez également attacher ce modèle en tant que valeur d'un deuxième module, que vous attachez ensuite en tant que dépendance à votre module principal.
Je pense que sa solution est bien meilleure que celle actuellement acceptée car
La façon dont Angular semble fonctionner dans la plupart des autres exemples que j'ai vus a le contrôleur définissant les données du modèle, ce qui n'a jamais eu de sens pour moi, il n'y a pas de séparation entre le modèle et le contrôleur, cela ne semble pas vraiment MVC pour moi. Cette solution vous permet d'avoir vraiment un objet modèle complètement séparé que vous passez dans le contrôleur. Notez également que si vous utilisez la directive ng-include, vous pouvez mettre tout votre code HTML angulaire dans un fichier séparé, séparant complètement votre vue de modèle et votre contrôleur en pièces modulaires distinctes.
la source
Si vous utilisez angular-ui-router, alors c'est la bonne solution: https://github.com/angular-ui/ui-router/wiki#resolve
Fondamentalement, vous déclarez un ensemble de dépendances à «résoudre» avant que le contrôleur ne soit instancié. Vous pouvez déclarer des dépendances pour chacun de vos "états". Ces dépendances sont ensuite passées dans le "constructeur" du contrôleur.
la source
Une façon de le faire serait d'avoir un service distinct qui peut être utilisé comme un «navire» pour les arguments où ils sont membres de données publiques.
la source
Je n'ai pas vraiment aimé les solutions ici pour mon cas d'utilisation particulier, alors j'ai pensé que je publierais ce que j'ai fait parce que je ne l'ai pas vu ici.
Je voulais simplement utiliser un contrôleur plus comme une directive, dans une boucle ng-repeat:
Maintenant, afin d'accéder à la
objParameter
création dans chaque DirectiveLikeController (ou pour obtenir l'objParameter à jour à TOUT MOMENT), tout ce que je dois faire est d'injecter $ scope et d'appeler$scope.$eval('objParameter')
:Le seul véritable inconvénient que je vois est qu'il nécessite que le contrôleur parent sache que le paramètre est nommé
objParameter
.la source
Non ce n'est pas possible. Je pense que vous pouvez utiliser ng-init comme hack http://docs.angularjs.org/api/ng.directive:ngInit .
la source
ng-init
se produireVoici une solution (basée sur la suggestion de Marcin Wyszynski) qui fonctionne là où vous voulez passer une valeur dans votre contrôleur mais vous ne déclarez pas explicitement le contrôleur dans votre html (ce que ng-init semble exiger) - si, par exemple, vous rendez vos modèles avec ng-view et déclarez chaque contrôleur pour l'itinéraire correspondant via routeProvider.
JS
html
Dans cette solution, CurrentUser est un service qui peut être injecté dans n'importe quel contrôleur, la propriété .name étant alors disponible.
Deux notes:
un problème que j'ai rencontré est que .name est défini après le chargement du contrôleur, donc comme solution de contournement j'ai un court délai avant de rendre le nom d'utilisateur sur la portée du contrôleur. Existe-t-il une manière élégante d'attendre que .name ait été défini sur le service?
cela semble être un moyen très facile d'obtenir un utilisateur actuel dans votre application Angular avec toute l'authentification conservée en dehors d'Angular. Vous pouvez avoir un before_filter pour empêcher les utilisateurs non connectés d'accéder au code HTML où votre application Angular est démarrée, et dans ce code HTML, vous pouvez simplement interpoler le nom de l'utilisateur connecté et même son ID si vous souhaitez interagir avec les détails de l'utilisateur. via les requêtes http de votre application Angular. Vous pouvez autoriser les utilisateurs non connectés à utiliser l'application angulaire avec un «utilisateur invité» par défaut. Tout conseil sur les raisons pour lesquelles cette approche serait mauvaise serait le bienvenu - il semble trop facile d'être raisonnable!)
la source
Il s'agit d'une extension de l' excellente réponse de @Michael Tiller . Sa réponse fonctionne pour initialiser des variables de la vue en injectant l'
$attrs
objet dans le contrôleur. Le problème se produit si le même contrôleur est appelé$routeProvider
lorsque vous naviguez par routage. Ensuite, vous obtenez une erreur d'injecteurUnknown provider : $attrsProvider
car elle$attrs
n'est disponible pour l'injection que lorsque la vue est compilée. La solution consiste à transmettre la variable (foo)$routeParams
lors de l'initialisation du contrôleur à partir de la route et$attrs
lors de l'initialisation du contrôleur à partir de la vue. Voici ma solution.De la route
Cela gère une URL telle que
'/mypage/bar'
. Comme vous pouvez le voir, foo est passé par url param et nous fournissons$injector
un objet vide pour$attrs
aucune erreur d'injecteur.De la vue
Maintenant, le contrôleur
la source