J'ai une directive de formulaire qui utilise un callback
attribut spécifié avec une portée d'isolat:
scope: { callback: '&' }
Il se trouve à l'intérieur d'un ng-repeat
afin que l'expression que je passe inclut le id
de l'objet comme argument de la fonction de rappel:
<directive ng-repeat = "item in stuff" callback = "callback(item.id)"/>
Quand j'ai fini avec la directive, elle appelle $scope.callback()
depuis sa fonction de contrôleur. Dans la plupart des cas, c'est bien, et c'est tout ce que je veux faire, mais parfois j'aimerais ajouter un autre argument de l'intérieur de directive
lui - même.
Existe-t-il une expression angulaire qui permettrait ceci $scope.callback(arg2)
:, résultant en callback
un appel avec arguments = [item.id, arg2]
?
Sinon, quelle est la meilleure façon de procéder?
J'ai trouvé que cela fonctionne:
<directive
ng-repeat = "item in stuff"
callback = "callback"
callback-arg="item.id"/>
Avec
scope { callback: '=', callbackArg: '=' }
et la directive appelant
$scope.callback.apply(null, [$scope.callbackArg].concat([arg2, arg3]) );
Mais je ne pense pas que ce soit particulièrement soigné et que cela implique de mettre des éléments supplémentaires dans la portée d'isolat.
Y a-t-il un meilleur moyen?
Plunker aire de jeux ici (avoir la console ouverte).
la source
ng
API, par exempleng-click="someFunction()"
une expression qui évalue l'exécution d'une fonction.$scope.callback
est défini par l'callback="someFunction"
attribut et lascope: { callback: '=' }
propriété de l'objet de définition de directive.$scope.callback
est une fonction à appeler ultérieurement. La valeur réelle de l'attribut est évidemment une chaîne - c'est toujours le cas avec HTML.Réponses:
Si vous déclarez votre rappel comme mentionné par @ lex82 comme
Vous pouvez appeler la méthode de rappel dans la portée de la directive avec la mappe d'objets et elle ferait la liaison correctement. Comme
sans avoir besoin de $ parse. Voir mon violon (journal de la console) http://jsfiddle.net/k7czc/2/
Mise à jour : il y a un petit exemple de ceci dans la documentation :
la source
Rien de mal avec les autres réponses, mais j'utilise la technique suivante pour passer des fonctions dans un attribut de directive.
Laissez les parenthèses lorsque vous incluez la directive dans votre html:
Puis «dépliez» la fonction dans le lien ou le contrôleur de votre directive. Voici un exemple:
L'étape de "dépliage" permet d'appeler la fonction en utilisant une syntaxe plus naturelle. Cela garantit également que la directive fonctionne correctement même lorsqu'elle est imbriquée dans d'autres directives susceptibles de transmettre la fonction. Si vous n'avez pas fait le déballage, alors si vous avez un scénario comme celui-ci:
Ensuite, vous vous retrouveriez avec quelque chose comme ça dans votre directive interne:
Ce qui échouerait dans d'autres scénarios d'imbrication.
J'ai adapté cette technique à partir d'un excellent article de Dan Wahlin à http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-3-isolate-scope-and-function-parameters
J'ai ajouté l'étape de déballage pour rendre l'appel de la fonction plus naturel et pour résoudre le problème d'imbrication que j'avais rencontré dans un projet.
la source
this
pointeur à l'intérieur de la méthode de rappel, car il utilise la portée de la directive. J'utilise Typescript et mon rappel ressemble à ceci:public validateFirstName(firstName: string, fieldName: string): ng.IPromise<boolean> { var deferred = this.mQService.defer<boolean>(); ... .then(() => deferred.resolve(true)) .catch((msg) => { deferred.reject(false); }); return deferred.promise; }
Dans la directive (
myDirective
):Dans le modèle de directive:
En source:
...où
myFunction
est défini dans le contrôleur.Notez que
param
dans le modèle de directive se lie parfaitement àparam
dans la source et est défini suritem
.Pour appeler depuis la
link
propriété d'une directive ("à l'intérieur" de celle-ci), utilisez une approche très similaire:la source
Oui, il existe un meilleur moyen: vous pouvez utiliser le service $ parse dans votre directive pour évaluer une expression dans le contexte de la portée parente tout en liant certains identificateurs de l'expression à des valeurs visibles uniquement dans votre directive:
Ajoutez cette ligne à la fonction de lien de la directive où vous pouvez accéder aux attributs de la directive.
Votre attribut de rappel peut alors être défini comme
callback = "callback(item.id, arg2)"
parce que arg2 est lié à yourSecondArgument par le service $ parse à l'intérieur de la directive. Les directives tellesng-click
que vous permettent d'accéder à l'événement click via l'$event
identifiant à l'intérieur de l'expression passée à la directive en utilisant exactement ce mécanisme.Notez que vous ne devez pas faire
callback
un membre de votre étendue isolée avec cette solution.la source
scope.$parent
rend la directive "fuyante" - elle "connaît" trop le monde extérieur, ce qu'un composant encapsulé bien conçu ne devrait pas.Pour moi, la suite a fonctionné:
dans la directive, déclarez-le comme ceci:
Dans le modèle de directive, utilisez-le de la manière suivante:
Et puis lorsque vous utilisez la directive, passez la fonction comme ceci:
Vous passez la fonction par sa déclaration et elle est appelée à partir de la directive et les paramètres sont renseignés.
la source