En este tutorial, aprenda a crear una aplicación Angular que consuma los servicios OData de Sitefinity CMS mediante el SDK OData fácil de usar de Sitefinity.
Sitefinity CMS proporciona potentes capacidades de administración de contenido y API sólidas para consumir contenido a través de los servicios OData, lo que le permite implementar casos de uso de CMS sin cabeza. En tales escenarios, usted crea y organiza su contenido a través de Sitefinity CMS, y lo expone utilizando la API RESTFul lista para usar. Este enfoque le permite desarrollar y entregar este contenido en varios dispositivos y aprovechar los marcos de frontend más populares.
En esta publicación se muestra cómo crear una aplicación Angular que consume los servicios OData de Sitefinity CMS. No tiene que estar demasiado familiarizado con las solicitudes HTTP o el protocolo OData, ya que usaremos el SDK OData de Sitefinity (también conocido a continuación como WebServices SDK). El SDK está disponible a través de npm y tiene una API simple y completa. Estaremos en constante evolución del SDK en 2019 con más mejoras funcionales y de documentación.
ng new QuantumHeadlessAngularApp
npm install sitefinity-webservices-sdk --save
"scripts":[
"node_modules/sitefinity-webservices-sdk/dist/sitefinity-webservices-sdk.js"
]
providers:[
{ provide:'Sitefinity', useValue: window['Sitefinity']},
]
El servicio Sitefinity proporciona instancias únicas del objeto Sitefinity SDK y el objeto de consulta SDK. Inyectamos Sitefinity en el constructor del servicio e inicializamos la instancia. Se necesita un serviceUrl
, que apunte al servicio OData predeterminado de su proyecto Sitefinity hospedado. La URL del servicio se construye añadiendo /appi/default a su dominio del sitio web de Sitefinity. Por ejemplo:
http://site17899124552543.srv06.sandbox.sitefinity.com/api/default/
import{Inject, Injectable}from'@angular/core';
import{SettingsService}from'./settings.service';
const endpoint = '/api/default/';
@Inyectable({
providedIn: 'root'})export class SitefinityService {private sitefinity: any; private queryInstance: cualquiera; get instance(): any {if(! este. sitefinity) {este. initializeInstance(); }devuelve estearchivo . sitefinity; }get query(): any {devuelve esto. queryInstance; }constructor(@Inject('Sitefinity') private sf, private settings: SettingsService) {}private initializeInstance(){const serviceUrl
= '${this. configuración. url}${endpoint}'; if(serviceUrl) {este. sitefinity = nuevo este. sf({serviceUrl}); este.
queryInstance = nuevo este. sf. Consulta(); }}}
La aplicación consta de un menú de navegación y dos páginas:Noticias y Showcases.
La página Noticias muestra una lista de noticias. La funcionalidad adicional proporciona a los usuarios la capacidad de cargar más contenido y filtrarlo por taxonomía (etiquetas y categorías).
La segunda página muestra una lista de showcases (donde showcases es un tipo de contenido dinámico que creamos en la prueba alojada). Los usuarios podrán buscar noticias, vitrinas e imágenes.
El diseño general de la aplicación y sus partes reutilizables se encuentran en el layout.component
archivo . La plantilla de la layout.component
consiste en una navegación, una barra de búsqueda, una imagen de encabezado y un contenedor para diferentes contenidos en las páginas. Aquí hay un breve resumen de la funcionalidad contenida en cada componente:
NewsItemsComponent
Muestra una lista de noticias. Una vez inicializado el componente, llamamos al getNewsItems
método para cargar la lista.
ngOnInit(){
this.getNewsItems
();
}
En el getNewsItems
método del servicio NewsItems puede ver cómo obtener newsItems de Sitefinity, mediante el SDK de WebServices.
getNewsItems
(): Observable<NewsItem[]>{
let query;
const=newReplaySubject<NewsItem[]>(1);
=this.sitefinity
.query
.select('Title','Id','Content','DateCreated','PublicationDate','Summary','UrlName','Author','Tags','Category','Featured')
.
expand('Miniatura'). orden(«PublicationDate desc»); este. sitefinity. instancia. data(newsItemsDataOptions). obtener({
query: query,successCb: data => newsReplaySubject. siguiente(datos. value as NewsItem[]),failureCb: data => console. registro(datos)}); volver noticiasReplaySubject. asObservable(); }
OData admite varios tipos de opciones de consulta para consultar datos. Los parámetros de consulta le dan la opción de modificar su solicitud con pares clave-valor. La implementación de la consulta, proveniente del SDK de Sitefinity WebServices, simplifica esta sintaxis, por lo que puede usar métodos como seleccionar, expandir, ordenar, dónde, etc. Por ejemplo, en nuestro getNewsItems
método, utilizamos la consulta Sitefinity para seleccionar las propiedades deseadas que se devolverán, obtener los elementos de datos relacionados y especificar el orden de los resultados. Dado que la propiedad Thumbnail es un campo relacionado, usamos el método expand para rellenar su valor.
La instancia del objeto Sitefinity se puede configurar utilizando el objeto de datos, donde pasamos información sobre el tipo de contenido, el proveedor y la cultura.
exportconst={
urlName:'newsitems',
providerName:'OpenAccessDataProvider',
cultureName:'en'
};
Volviendo al NewsComponent
, inyectamos el NewsService
en el constructor. En la implementación del getNewsItems
método nos suscribimos al getNewsItems
método del NewsService
. Asignamos las noticias recuperadas a una propiedad pública de la NewsItems
clase, para que podamos usarla en la plantilla del componente.
this.=this.newsService.getAllNews().
subscribe((data: NewsItem[]) = > {if (data) {this. noticiasArtículos. push(datos); }});
Para implementar una funcionalidad Cargar más, ampliamos la consulta con los métodos skip y take.
=this.sitefinity
.query
.select('Title','Id','Content','DateCreated','PublicationDate','Summary','UrlName','Author','Tags','Category','Featured')
.expand('Thumbnail')
.order('PublicationDate desc')
.skip(skip).take(take);
Así es como debería ser la implementación del método final getNewsItems
de nuestro servicio:
getNewsItems(take?:number, skip?:number): Observable<NewsItem[]>{
let query;
const=newReplaySubject<NewsItem[]>(1);
if((!==null
&& take !== undefined) && (skip !== null && skip !== undefined)) {
query = este. sitefinity
. consulta
. seleccionar('Título', 'Id', 'Contenido', 'FechaCreada', 'PublicationDate', 'Resumen', 'UrlName', 'Autor', 'Etiquetas', 'Categoría', 'Destacado'). expand('Miniatura'). orden('PublicationDate desc'). saltar(omitir). tomar(tomar); } else {
query = este. sitefinity
. consulta
. seleccionar('Título', 'Id', 'Contenido', 'FechaCreada', 'PublicationDate', 'Resumen', 'UrlName', 'Autor','Etiquetas', 'Categoría', 'Destacado'). expand('Miniatura'). orden(«PublicationDate desc»); }este. sitefinity. instancia. data(newsItemsDataOptions). obtener({
query: query,successCb: data => newsReplaySubject. siguiente(datos. value as NewsItem[]),failureCb: data => console. registro(datos)}); volver noticiasReplaySubject. asObservable(); }
La obtención de un único newsItem con el SDK se realiza mediante el getSingle
método de la instancia. Así es como obtenemos un newsItem por id en el NewsService
archivo .
getNewsItem(id:string): Observable<NewsItem>{
const=newReplaySubject<any>(1);
this.sitefinity.instance.data(newsItemsDataOptions).getSingle({
key: id,
query:this.sitefinity
.query
.select('Title','Id','Content','DateCreated','Summary','UrlName','Author','Tags')
.expand('Thumbnail')
.order('Title desc'),
successCb: (data: NewsItem) => {newsReplaySubject. next(data)},failureCb: data => console. registro(datos)}); volver noticiasReplaySubject. asObservable(); }
En la página de Noticias, también podemos filtrar por etiqueta y por categoría. Hacemos esto implementando un getNewsByTaxa
método del , donde NewsService
propertyName es el nombre del campo de taxonomía (por ejemplo, "Etiquetas" o "Categoría") y taxaId es el Id de la taxonomía por la que estamos filtrando.
getNewsByTaxa(propertyName:string, taxaId:string): Observable<NewsItem[]>{
const=newReplaySubject<any>(1);
this.sitefinity.instance.data(newsItemsDataOptions).get({
query:this.sitefinity
.query
.select('Title','Id','Content','DateCreated','Summary','UrlName','Author')
.expand('Thumbnail')
.order('Title desc')
.where()
. cualquiera(). eq(propertyName, taxaId). hecho(). done(),successCb: data => newsSubject. siguiente(datos. value as NewsItem[]),failureCb: data => console. registro(datos)}); volver noticiasSujeto. asObservable(); }
Observe cómo estamos utilizando el método where de la consulta Sitefinity en la getNewsByTaxa
implementación. La sintaxis es sencilla y admite operaciones de filtrado estándar.
Tenga en cuenta el doble uso del done()
método, que es necesario porque la última llamada al mismo finaliza la definición de la consulta actual. Еach operador lógico (por ejemplo, eq, y, o, contiene, etc.) requiere volver a llamar al método done. Esto es específico de la implementación actual del SDK de Sitefinity OData y está sujeto a refactorización en las versiones futuras, donde solo se necesitará una llamada done()
a.
.where()
.any()
.eq(propertyName, taxaId)
.done().done()
El último método que tenemos en el servicio de Noticias es:
getAllNewsCount(): Observable<number>{
const=newReplaySubject<any>(1);
this.sitefinity.instance.
data(newsItemsDataOptions). obtener({
consulta: este. sitefinity
. consulta
. count(false),successCb: (data: number) => newsReplaySubject. next(data),failureCb: data => consola. registro(datos)}); volver noticiasReplaySubject. asObservable(); }
De forma predeterminada, el método count devuelve todos los elementos, así como su recuento. Sin embargo, al pasar false como argumento, el método devuelve sólo el recuento. En nuestra aplicación utilizamos este método para comprobar cuándo se debe mostrar el enlace Mostrar más.
Otra parte importante de la aplicación es la funcionalidad de búsqueda. Queremos buscar en múltiples tipos de contenido: imágenes, vitrinas y noticias. Para esto utilizamos la funcionalidad de solicitud por lotes del SDK, que nos permite combinar múltiples solicitudes HTTP en una.
privategetItemsBySearchWord(searchWord:string):void{
const=this.sitefinity.instance.batch(data=>this._searchResults.next(this.mapSearchResults(data)));
batch.get({ entitySet:'showcases', query:this.sitefinity
.query
.
seleccione('Título', 'Cliente', 'Desafío', 'Solución', 'Resultados', 'Id'). orden('Título asc'). donde(). o(). contiene('Título', searchWord). o(). contiene('Cliente', searchWord). o(). contiene('Desafío', searchWord). o(). contiene('Solución', searchWord). o(). contiene('Resultados', searchWord). hecho(). hecho(). hecho(). hecho(). hecho(). hecho()});
lote. get({ entitySet: 'images', query: this. sitefinity
. consulta
. donde().
contiene('Título', searchWord). hecho()});
lote. get({ entitySet: 'newsitems', query: this. sitefinity
. consulta
. seleccione('Título', 'Contenido', 'Resumen', 'Id'). orden('Título asc'). donde(). o(). contiene('Título', searchWord). o(). contiene('Contenido', searchWord). o(). contiene('Resumen', searchWord). hecho(). hecho(). hecho(). hecho()});
lote. ejecutar(); }
Para encadenar las solicitudes, creamos una instancia de un nuevo lote desde la instancia de Sitefinity, pasando una devolución de llamada para el resultado. A continuación, llamamos al método get del objeto batch para cada tipo de contenido que nos gustaría solicitar. Para finalizar la solicitud por lotes, utilizamos el batch.execute()
método.
Esperamos que esta publicación de blog lo haya ayudado a comenzar con los servicios OData de Sitefinity y que haya disfrutado trabajando con el SDK. Si tiene alguna pregunta, envíenos una línea en la sección de comentarios a continuación. Si eres nuevo en Sitefinity, puedes obtener más información aquí o saltar directamente y comenzar tu prueba gratuita de 30 días hoy.
¿Necesita ponerse al día con Sitefinity? Regístrese en nuestro curso gratuito diseñado para ayudar a los aspirantes a desarrolladores a aprovechar todo el potencial de Sitefinity.
Deje que nuestros expertos le enseñen cómo utilizar las mejores funciones de Sitefinity para ofrecer experiencias digitales atractivas.
Aprende másSuscríbete para recibir todas las noticias, información y tutoriales que necesitas para crear mejores aplicaciones y sitios de negocios