Your search did not match any results.
Scheduler

SignalR Service

This demo shows how you can use a SignalR service to synchronize appointments across different devices. To emulate such a setup, each Scheduler on this page reads data from its own separate data store. Changes made in one control are repeated in the other and persist until the browser session has expired.

Follow the steps below to implement this functionality. Note again that this demo repeats all steps twice for the two Schedulers. Your project will have a single control and a single store.

  1. Configure a CustomStore. In this demo, we use the createStore method (part of the DevExtreme.AspNet.data extension).

  2. Create the Scheduler and use its dataSource property to bind it to the store instance.

  3. When a push notification is received, call the store's push(changes) method to update the store's data (see the connection.on event handlers).

For server-side configuration, refer to the ASP.NET MVC version of this demo.

For more information about integration with push services, refer to the following help topic: Integration with Push Services.

Copy to CodeSandBox
Apply
Reset
<div class="schedulers"> <div class="column-1"> <dx-scheduler timeZone="America/Los_Angeles" [dataSource]="store1" [remoteFiltering] ="true" [views]='["day", "workWeek"]' currentView="day" [currentDate]="currentDate" [startDayHour]="9" [endDayHour]="19" [height]="600" textExpr="Text" dateSerializationFormat="yyyy-MM-ddTHH:mm:ssZ" descriptionExpr="Description" startDateExpr="StartDate" endDateExpr="EndDate" allDayExpr="AllDay"> </dx-scheduler> </div> <div class="column-2"> <dx-scheduler timeZone="America/Los_Angeles" [dataSource]="store2" [remoteFiltering] ="true" [views]='["day", "workWeek"]' currentView="day" [currentDate]="currentDate" [startDayHour]="9" [endDayHour]="19" [height]="600" dateSerializationFormat="yyyy-MM-ddTHH:mm:ssZ" textExpr="Text" startDateExpr="StartDate" endDateExpr="EndDate" allDayExpr="AllDay"> </dx-scheduler> </div> </div>
import { NgModule, Component, enableProdMode } from '@angular/core'; import {BrowserModule} from '@angular/platform-browser'; import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; import { HubConnectionBuilder, HttpTransportType } from '@aspnet/signalr'; import {DxSchedulerModule} from 'devextreme-angular'; import * as AspNetData from 'devextreme-aspnet-data-nojquery'; if (!/localhost/.test(document.location.host)) { enableProdMode(); } const BASE_PATH = 'https://js.devexpress.com/Demos/NetCore/'; const url = BASE_PATH + 'api/SchedulerSignalR'; const createStore = () => AspNetData.createStore({ key: 'AppointmentId', loadUrl: url, insertUrl: url, updateUrl: url, deleteUrl: url, onBeforeSend: function(method, ajaxOptions) { ajaxOptions.xhrFields = { withCredentials: true }; } }); const store1 = createStore(); const store2 = createStore(); const connection = new HubConnectionBuilder() .withUrl(BASE_PATH + 'schedulerSignalRHub', { skipNegotiation: true, transport: HttpTransportType.WebSockets }) .build(); connection .start() .then(() => { connection.on('update', (key, data) => { store1.push([{ type: 'update', key: key, data: data }]); store2.push([{ type: 'update', key: key, data: data }]); }); connection.on('insert', (data) => { store1.push([{ type: 'insert', data: data }]); store2.push([{ type: 'insert', data: data }]); }); connection.on('remove', (key) => { store1.push([{ type: 'remove', key: key }]); store2.push([{ type: 'remove', key: key }]); }); }); @Component({ selector: 'demo-app', templateUrl: 'app/app.component.html', styleUrls: ['app/app.component.css'] }) export class AppComponent { store1: any; store2: any; currentDate: Date = new Date(2021, 4, 25); constructor() { this.store1 = store1; this.store2 = store2; } } @NgModule({ imports: [ BrowserModule, DxSchedulerModule ], declarations: [AppComponent], bootstrap: [AppComponent] }) export class AppModule { } platformBrowserDynamic().bootstrapModule(AppModule)
::ng-deep .schedulers { display: flex; } ::ng-deep .column-1 { padding-right: 5px; } ::ng-deep .column-2 { padding-left: 5px; } ::ng-deep .dx-scheduler-small .dx-scheduler-view-switcher.dx-tabs { display: table; }
// In real applications, you should not transpile code in the browser. You can see how to create your own application with Angular and DevExtreme here: // https://js.devexpress.com/Documentation/Guide/Angular_Components/Getting_Started/Create_a_DevExtreme_Application/ System.config({ transpiler: 'ts', typescriptOptions: { module: "system", emitDecoratorMetadata: true, experimentalDecorators: true }, meta: { 'typescript': { "exports": "ts" }, 'devextreme-aspnet-data-nojquery': { "esModule": true }, 'devextreme/localization.js': { "esModule": true } }, paths: { 'npm:': 'https://unpkg.com/' }, map: { 'ts': 'npm:plugin-typescript@8.0.0/lib/plugin.js', 'typescript': 'npm:typescript@3.5.3/lib/typescript.js', '@angular': 'npm:@angular', 'tslib': 'npm:tslib@2.1.0/tslib.js', 'rxjs': 'npm:rxjs@6.4.0', '@aspnet/signalr': 'npm:@aspnet/signalr@1.0.0/dist/cjs/index.js', 'devextreme-aspnet-data-nojquery': 'npm:devextreme-aspnet-data-nojquery@2.7.1/index.js', 'rrule': 'npm:rrule@2.6.6/dist/es5/rrule.js', 'luxon': 'npm:luxon@1.26.0/build/global/luxon.min.js', 'es6-object-assign': 'npm:es6-object-assign@1.1.0', 'devextreme': 'npm:devextreme@20.2.6', 'jszip': 'npm:jszip@3.6.0/dist/jszip.min.js', 'devextreme-quill': 'npm:devextreme-quill@0.10.3/dist/dx-quill.min.js', 'devexpress-diagram': 'npm:devexpress-diagram@2.0.18', 'devexpress-gantt': 'npm:devexpress-gantt@2.0.24', 'devextreme-angular': 'npm:devextreme-angular@20.2.6', 'preact': 'npm:preact@10.5.13/dist/preact.js', 'preact/hooks': 'npm:preact@10.5.13/hooks/dist/hooks.js' }, packages: { 'app': { main: './app.component.ts', defaultExtension: 'ts' }, 'devextreme': { defaultExtension: 'js' }, 'devextreme/events/utils': { main: 'index' }, 'devextreme/events': { main: 'index' }, 'es6-object-assign': { main: './index.js', defaultExtension: 'js' } }, packageConfigPaths: [ "npm:@angular/*/package.json", "npm:@angular/common/*/package.json", "npm:rxjs/package.json", "npm:rxjs/operators/package.json", "npm:devextreme-angular/*/package.json", "npm:devextreme-angular/ui/*/package.json", "npm:devextreme-angular/package.json", "npm:devexpress-diagram/package.json", "npm:devexpress-gantt/package.json", "npm:@aspnet/*/package.json", ] });
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>DevExtreme Demo</title> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/20.2.6/css/dx.common.css" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/20.2.6/css/dx.light.css" /> <script src="../signalr-session-id.js"></script> <script src="https://unpkg.com/core-js@2.4.1/client/shim.min.js"></script> <script src="https://unpkg.com/zone.js@0.10.2/dist/zone.js"></script> <script src="https://unpkg.com/reflect-metadata@0.1.3/Reflect.js"></script> <script src="https://unpkg.com/systemjs@0.21.3/dist/system.js"></script> <script src="config.js"></script> <script> System.import('app').catch(console.error.bind(console)); </script> </head> <body class="dx-viewport"> <div class="demo-container"> <demo-app>Loading...</demo-app> </div> </body> </html>