Mode optimal / préféré pour appeler 'SP.ClientContext.executeQueryAsync' dans SharePoint

J'ai appris le modèle d'objet côté client et j'ai rencontré la méthode executeQueryAsync . J'ai trouvé qu'il y a plusieurs façons d'appeler cette méthode. Certains de ceux que j'ai trouvé étaient ceux-ci:

 var context = new SP.ClientContext.get_current(); // Option 1 context.executeQueryAsync( function(sender, args){ }, function(sender, args){ } ); // Option 2 context.executeQueryAsync( Function.createDelegate(this, _onSucceed), Function.createDelegate(this, _onFail) ); // Option 3 context.executeQueryAsync( Function.createDelegate(this, this._onSucceed), Function.createDelegate(this, this._onFail) ); // Option 4 context.executeQueryAsync(_onSucceed, _onFail); 

Quelle est la façon la plus optimale / préférée? Aussi, qu'est-ce que fait la déclaration Function.createDelegate ? La documentation de cette fonction semble être très cryptique pour moi.

Tout d'abord, je dirais qu'il n'y a pas de «manière optimale» car ces tous se comportent quelque peu différemment … Deuxièmement, j'ajouterais que ce n'est pas autant une chose spécifique à SharePoint ou à exécuterQueryAsync car il s'agit d'une chose JS en général …

Ensuite, nous devons comprendre que executeQueryAsync s'attend à ce que deux fonctions soient des arguments: la première est une fonction à exécuter si executeQueryAsync réussit, la seconde est une fonction à effectuer si la méthode rencontre une erreur. Ces fonctions sont des paramètres passés (à partir de executeQueryAsync , et non à partir de votre JS) représentant l'objet d'envoi ainsi qu'un objet argument qui peut avoir des données ( args.get_message() et args.get_stackTrace() sont communs dans le cas d'un appel défectueux )

Dans votre exemple «Option 1», executeQueryAsync reçoit deux fonctions anonymes, vous ne pourrez pas les réutiliser n'importe où, mais si le comportement est simple, cela peut suffire.

Dans l'option 2, vous utilisez la méthode createDelegate pour donner un contexte aux rappels d'échec et de réussite – cela createDelegate la createDelegate de la portée est dans JavaScript; Si vous devez faire référence à une variable qui n'est accessible que dans la fonction qui appelle executeQueryAsync , vous devrez utiliser ce type de motif afin que this dans le rappel renvoie la fonction appelée executeQueryAsync au lieu de la fonction de réussite ou d'échec que vous avez appelée " Re maintenant. Vous pouvez penser à créer un délégué en tant que fonction d'appel appelant sur une autre fonction, mais en disant «Je veux que cette fonction puisse voir ce que je peux voir, peu importe où il se trouve dans le code. Tout cela peut sembler un peu arrogant, mais tel est la portée dans JavaScript … Vous pouvez contourner complètement la nécessité de le faire en faisant référence à des variables à des niveaux de portée plus élevés (par exemple, dans une fonction qui contient la méthode appelante ainsi que le succès et Méthodes d'échec)

L'option 3 ressemble à l'option 2, sauf qu'elle spécifie simplement que les fonctions _onSucceed ou _onFail devraient être celles qui sont contenues dans l'objet appelant

L'option 4 ressemble à l'option 1, sauf que vous avez nommé les fonctions (et qu'elles sont disponibles dans la portée actuelle) et les appelle par leur nom.

J'utilise habituellement quelque chose comme l'option 2, ou l'option 4 – mais j'espère que vous pouvez voir que cela dépend vraiment de la façon dont vous essayez de structurer votre code.

EDIT: en réponse à un commentaire sur Function.createDelagate() – Il semble simplement être un assistant dans une ressource de script ASP.NET; Il ne fait que l'appel à apply() (qui est la manière standard de JS de le faire – voir la documentation MDN ici ). Il pourrait également fournir une certaine compatibilité ascendante quelque part dans ASP.NET, mais je ne suis pas vraiment sûr!

Voici le code de la fonction à partir d'un fichier de ressources de script dans mon environnement SP:

 Function.createDelegate = function(a, b) { return function() { return b.apply(a, arguments) } }; 

Et en bonus, je pensais à la façon dont j'utilise executeQueryAsync et je me suis rendue compte que je l'utilisais plus souvent comme option 1, avec un modèle de promesse utilisant jQuery différé comme ceci:

 function getSPDataAsync(context) { var deferred = $.Deferred(); context.executeQueryAsync(function(sender, args) { deferred.resolve(sender, args); }, function(sender, args) { deferred.reject(sender, args); }); return deferred.promise(); } 

Ensuite, vous pouvez faire des choses un peu moins spaghetti, comme:

 ... ctx.load(items); getSPDataAsync(ctx).then(function() { //do some stuff with the data when the promise resolves }); 

Juste au cas où quelqu'un se souciera! 🙂