Usar las API de JavaScript de SharePoint para trabajar con datos de SharePoint
Este es el décimo artículo de una serie sobre los conceptos básicos de desarrollo de complementos de SharePoint hospedados en SharePoint. Primero debe familiarizarse con Complementos de SharePoint y con los anteriores artículos de esta serie, los cuales puede encontrar en Introducción a la creación de complementos de SharePoint hospedados en SharePoint | Pasos siguientes.
Nota
Si ha estado trabajando en esta serie sobre complementos hospedados por SharePoint, hay una solución de Visual Studio que puede usar para continuar con este tema. También puede descargar el repositorio que encontrará en SharePoint_SP-hosted_Add-Ins_Tutorials y abrir el archivo BeforeJSOM.sln.
Aunque los complementos de SharePoint hospedados en SharePoint no pueden tener código en el lado del servidor, es posible tener una lógica corporativa y una interacción de tiempo de ejecución con los componentes de SharePoint en un complemento de SharePoint hospedado en SharePoint mediante JavaScript y la biblioteca de modelo de objetos de cliente de JavaScript para SharePoint. Se le llama JSOM. Tenga en cuenta la "M" al final. No lo confunda con JSON (notación de objetos JavaScript). En este artículo, usará el modelo de objetos de JavaScript para buscar y eliminar elementos antiguos de la lista Nuevos empleados en Seattle.
Compruebe que se completó el paso siguiente del primer tutorial de esta serie:
Abra el archivo /Pages/Default.aspx de la raíz del proyecto. Entre otras cosas, este archivo generado carga uno o ambos scripts que se hospedan en SharePoint: sp.runtime.js y sp.js. La marca para cargar estos archivos está en el control Content situado cerca de la parte superior del archivo que tiene el identificador
PlaceHolderAdditionalPageHead
. La revisión varía según la versión de Microsoft Office Developer Tools para Visual Studio que está usando.Esta serie de tutoriales requiere que ambos archivos se carguen mediante etiquetas HTML de
<script>
, no con etiquetas de<SharePoint:ScriptLink>
. Asegúrese de que las líneas siguientes están en el controlPlaceHolderAdditionalPageHead
, justo encima de la línea<meta name="WebPartPageExpansion" content="full" />
:<script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script> <script type="text/javascript" src="/_layouts/15/sp.js"></script>
A continuación, busque en el archivo cualquier otra marca que también permita cargar uno de estos archivos y quite la marca redundante. Guarde y cierre el archivo.
En el nodo Scripts del Explorador de soluciones, debería haber un archivo Add-in.js. Si no está, pero hay un archivo App.js, haga clic con el botón derecho en App.js y cambie el nombre por Add-in.js. Si no hay un Add-in.js o App.js, cree uno siguiendo estos pasos:
Haga clic con el botón derecho en el nodo Scripts y seleccione Agregar>Nuevo elemento>Web.
Seleccione Archivo JavaScript y asígnele el nombre Add-in.js.
Actualice el código de la página aspx para que haga referencia al archivo JS correcto: cámbielo de:
<script type="text/javascript" src="../Scripts/App.js"></script>
a
<script type="text/javascript" src="../Scripts/Add-in.js"></script>
Abra Add-in.js y elimine el contenido que tenga.
Agregue las siguientes líneas al archivo.
'use strict'; var clientContext = SP.ClientContext.get_current(); var employeeList = clientContext.get_web().get_lists().getByTitle('New Employees In Seattle'); var completedItems;
Tenga en cuenta lo siguiente en relación con este código:
- La línea
'use strict';
garantiza que el tiempo de ejecución de JavaScript en el explorador generará una excepción si sigue accidentalmente determinadas prácticas incorrectas en el JavaScript. - La
clientContext
variable contiene unSP.ClientContext
objeto que hace referencia al sitio web de SharePoint. Todo el código JSOM comienza creando u obteniendo una referencia a un objeto de este tipo. - La variable
employeeList
contiene una referencia a la instancia de lista Nuevos empleados de Seattle. - La variable
completedItems
contiene los elementos de la lista que eliminará el script: los elementos cuyo campo OrientationStage esté establecido en Completado.
- La línea
Para minimizar los mensajes entre el explorador del cliente y el servidor de SharePoint, JSOM usa un sistema de procesamiento por lotes. Solo una función,
SP.ClientContext.executeQueryAsync
, envía realmente mensajes al servidor (y recibe respuestas).Las llamadas a la API de JSOM que se incluyen entre las llamadas de
executeQueryAsync
se agrupan y se envían al servidor en un lote la próxima vez que se llama aexecuteQueryAsync
. Pero no es posible llamar a un método de un objeto JSOM a menos que el objeto se haya reducido para el cliente en una llamada anterior deexecuteQueryAsync
.El script va a llamar al método
SP.ListItem.deleteObject
de cada elemento completado en la lista, con dos llamadas deexecuteQueryAsync
: una para obtener una colección de los elementos completos de la lista, y una segunda para agrupar las llamadas dedeleteObject
y enviarlas al servidor para la ejecución.Empiece por crear un método para obtener los elementos de lista desde el servidor. Agregue el siguiente código al archivo.
function purgeCompletedItems() { var camlQuery = new SP.CamlQuery(); camlQuery.set_viewXml( '<View><Query><Where><Eq>' + '<FieldRef Name=\'OrientationStage\'/><Value Type=\'Choice\'>Completed</Value>' + '</Eq></Where></Query></View>'); completedItems = employeeList.getItems(camlQuery); }
Cuando esas líneas se envían al servidor y se ejecutan en él, crean una colección de elementos de lista, pero el script debe reducir esa colección para el cliente. Esto se realiza con una llamada a la función
SP.ClientContext.load
, así que agregue la siguiente línea al final del método.clientContext.load(completedItems);
Agregue una llamada de
executeQueryAsync
. Este método tiene dos parámetros que son funciones de devolución de llamada. La primera se ejecuta si el servidor ejecuta correctamente todos los comandos del lote. Si se produce un error en el servidor por algún motivo, se ejecuta la segunda. Creará estas dos funciones en los pasos siguientes. Agregue la línea siguiente al final del método.clientContext.executeQueryAsync(deleteCompletedItems, onGetCompletedItemsFail);
Finalmente, agregue la línea siguiente al final del método.
return false;
Si se devuelve
false
al botón ASP.NET que llamará a la función, se cancela el comportamiento predeterminado de los botones ASP.NET, que es volver a cargar la página. Volver a cargar la página provocaría una recarga del archivo Add-in.js. Y eso, a su vez, reiniciaría el objetoclientContext
.Si esta recarga se completa entre el momento en que
executeQueryAsync
envía la solicitud y el momento en que el servidor de SharePoint devuelve la respuesta, el objeto originalclientContext
no existirá para procesar la respuesta. La función se detendrá sin éxito ni fracaso de las devoluciones de llamada ejecutadas. (El comportamiento exacto podría variar según el explorador).Agregue la siguiente función,
deleteCompletedItems
, al archivo. Esta es la función que se ejecuta si la funciónpurgeCompletedItems
es correcta. Tenga en cuenta lo siguiente en relación con este código:- El método
SP.ListItem.get_id
devuelve el identificador del elemento de lista. Cada elemento de la matriz es un objetoSP.ListItem
. - El método
SP.List.getItemById
devuelve el objetoSP.ListItem
con el identificador especificado. - El método
SP.ListItem.deleteObject
marca el elemento de lista que se eliminará en el servidor cuando se realice la llamada deexecuteQueryAsync
. Antes de que se puedan eliminar, los elementos de la lista deben copiarse de la colección que se envía desde el servidor a una matriz. Si el script ha llamado al métododeleteObject
para cada elemento directamente en el buclewhile
, JavaScript podría producir un error al quejarse de que la longitud de la colección se está cambiando mientras la enumeración está en curso.
El mensaje de error no es verdadero de forma literal, porque el elemento no elimina realmente de ninguna parte hasta que las llamadas
deleteObject
se agrupen y se envíen al servidor, pero el JSOM está diseñado para imitar las excepciones que deberían producirse en el servidor (donde el código no debe cambiar el tamaño de una colección mientras se está enumerando la colección). Sin embargo, las matrices tienen un tamaño fijo, por lo que las llamadasdeleteObject
en un elemento de una matriz eliminan el elemento de la lista, pero no cambian el tamaño de la matriz.function deleteCompletedItems() { var itemArray = new Array(); var listItemEnumerator = completedItems.getEnumerator(); while (listItemEnumerator.moveNext()) { var item = listItemEnumerator.get_current(); itemArray.push(item); } var i; for (i = 0; i < itemArray.length; i++) { itemArray[i].deleteObject(); } clientContext.executeQueryAsync(onDeleteCompletedItemsSuccess, onDeleteCompletedItemsFail); }
- El método
Agregue la siguiente función,
onDeleteCompletedItemsSuccess
, al archivo. Esta es la función que se ejecuta si se eliminan correctamente los elementos completados (o si no hay ningún elemento completado en la lista).La línea
location.reload(true);
hace que la página se vuelva a cargar desde el servidor. Es muy útil porque el elemento web de la vista de lista en la página aún muestra los elementos completados hasta que se actualice la página. El archivo Add-in.js también se vuelve a cargar, pero esto no causa un problema porque no lo hará de una forma que interrumpa una función JavaScript en curso.function onDeleteCompletedItemsSuccess() { alert('Completed orientations have been deleted.'); location.reload(true); }
Agregue al archivo las dos funciones siguientes de devolución de llamada en caso de error.
// Failure callbacks function onGetCompletedItemsFail(sender, args) { alert('Unable to get completed items. Error:' + args.get_message() + '\n' + args.get_stackTrace()); } function onDeleteCompletedItemsFail(sender, args) { alert('Unable to delete completed items. Error:' + args.get_message() + '\n' + args.get_stackTrace()); }
Abra el archivo default.aspx y busque el elemento
asp:Content
con el identificadorPlaceHolderMain
.Agregue la siguiente marcación entre el elemento
WebPartPages:WebPartZone
y el primero de los dos elementosasp:Hyperlink
. El valor del controladorOnClientClick
esreturn purgeCompletedItems()
en lugar de solopurgeCompletedItems()
. Elfalse
que devuelve la función indica a ASP.NET que no vuelva a cargar la página.<p><asp:Button runat="server" OnClientClick="return purgeCompletedItems()" ID="purgecompleteditemsbutton" Text="Purge Completed Items" /></p>
Vuelva a compilar el proyecto en Visual Studio.
Para minimizar la necesidad de establecer manualmente la Fase de orientación de elementos de lista en Completada mientras se prueba el complemento, abra el archivo elements.xml de la instancia de lista NewEmployeesInSeattle (no elements.xml de la plantilla de lista NewEmployeeOrientation) y agregue la marcación
<Field Name="OrientationStage">Completed</Field>
como último elemento secundario a uno o más de los elementosRow
.El siguiente es un ejemplo del aspecto del elemento
Rows
.<Rows> <Row> <Field Name="Title">Tom Higginbotham</Field> <Field Name="Division">Manufacturing</Field> <Field Name="OrientationStage">Completed</Field> </Row> <Row> <Field Name="Title">Satomi Hayakawa</Field> <Field Name="OrientationStage">Completed</Field> </Row> <Row> <Field Name="Title">Cassi Hicks</Field> </Row> <Row> <Field Name="Title">Lertchai Treetawatchaiwong</Field> </Row> </Rows>
Habilite las ventanas emergentes en el explorador que Visual Studio usa durante la depuraci?n.
Use la tecla F5 para implementar y ejecutar el complemento. Visual Studio instala temporalmente el complemento en el sitio de SharePoint de prueba y ejecuta el complemento inmediatamente.
Se abre la página principal del complemento con uno o más elementos en la lista con Fase de orientación en Completada.
Figura 1. Lista antes de la purga de los elementos completados
Cuando la página de inicio del complemento se haya cargado, seleccione el botón Purgar elementos completados. Si la operación se realiza correctamente (es decir, si no hay mensajes de error), todos los elementos Completados se eliminan y se verá una ventana emergente que indica Las orientaciones completadas se eliminaron.
Cierre la ventana emergente. La página se vuelve a cargar y los elementos Completados ya no están en el elemento web de vista de lista.
Figura 2. Lista después de la purga de los elementos completados
Para finalizar la sesión de depuración, cierre la ventana del explorador o detenga la depuración en Visual Studio. Cada vez que seleccione F5, Visual Studio retirará la versión anterior del complemento e instalará la más reciente.
Trabajará con este complemento y con la solución de Visual Studio en otros artículos. Es recomendable que vuelva a retirar el complemento cuando deje de trabajar con él por un tiempo. Haga clic con el botón derecho en el proyecto en el Explorador de soluciones y seleccione Retirar.
En el siguiente artículo de esta serie, agregaremos JavaScript a una página en la web de complemento que funciona con los datos de SharePoint en la web de host: Trabajar con datos de web de host de JavaScript en la web de complemento.