Share via


Il presente articolo è stato tradotto automaticamente.

ASP.NET MVC 5

Panoramica per gli sviluppatori .NET per le applicazioni a pagina singola

Lungo Le

Scaricare il codice di esempio

Una maggioranza degli sviluppatori Microsoft .NET Framework hanno trascorso la maggior parte della loro vita professionale sul lato server, codifica con .NET c# o Visual Basic quando la creazione di applicazioni Web. Naturalmente, JavaScript è stato utilizzato per le cose semplici come finestre modali, convalida, chiamate AJAX e così via. Tuttavia, JavaScript (codice lato client per la maggior parte) è stato sfruttato come lingua utilità e applicazioni in gran parte sono stata cacciate dal lato server.

Ultimamente c'è stata una tendenza enorme del codice dell'applicazione Web la migrazione dal lato server al lato client (browser) per soddisfare le aspettative degli utenti per UX fluido e reattivo. Con questo essere il caso, un sacco di sviluppatori .NET (specialmente nell'impresa) che fare con un'estrema quantità di ansia circa JavaScript consigliate, architettura, unit test, manutenibilità e la recente esplosione di diversi tipi di librerie JavaScript. Parte della tendenza dello spostamento di lato client è l'uso crescente di applicazioni a pagina singola (ZPS). Per dire che lo sviluppo SPA è il futuro è un eufemismo estremo. Terme sono come alcune delle migliori applicazioni sul Web offrono fluido UX e reattività, mentre minimizzano il payload (traffico) e round trip al server.

In questo articolo, rivolgo le ansie che potrebbero verificarsi quando si effettua la transizione dal lato server nel Regno SPA. Il modo migliore per affrontare queste ansie è ad abbracciare il JavaScript come linguaggio prima classe proprio come qualsiasi linguaggio .NET, ad esempio c#, .NET Visual Basic , Python e così via.

Di seguito sono alcuni principi fondamentali di sviluppo .NET che a volte vengono ignorati o dimenticati quando si sviluppano applicazioni in JavaScript:

  • Base di codice è gestibile in .NET perché sei decisivo con i limiti di classe e dove le classi effettivamente vivono all'interno dei vostri progetti.
  • Si separano preoccupazioni, quindi non è necessario che le classi che sono responsabili di centinaia di cose diverse, con sovrapposizione di responsabilità.
  • Avete repository riutilizzabili, query, entità (modelli) e fonti di dati.
  • Messo qualche pensiero in denominazione i file e le classi, quindi sono più significative.
  • Si pratica il buon uso dei modelli di progettazione, organizzazione e convenzioni di codifica.

Poiché questo articolo è per gli sviluppatori .NET che vengono introdotte nel mondo SPA, potrai inserire il minor numero di quadri possibili costruire una SPA gestibile con architettura sonora.

Creazione di un centro benessere in sette passaggi chiavi

Di seguito sono sette passaggi chiavi per convertire una nuova applicazione Web ASP.NET che è stato creato con il modello MVC ASP.NET di out-of-the-box Visual Studio 2013 in una SPA (con i riferimenti ai file di progetto appropriato che possono essere trovati nel download del codice).

  1. Scaricare e installare i pacchetti NuGet, RequireJS, RequireJS testo plug-in e Kendo UI Web.
  2. Aggiungere un modulo di configurazione (Northwind.Web/Scripts/app/main.js).
  3. Aggiungere un modulo di app (Northwind.Web/Scripts/app/app.js).
  4. Aggiungere un modulo di router (Northwind.Web/Scripts/app/router.js).
  5. Aggiungere un'azione e Mostra entrambi denominati Spa (Northwind.Web/Controllers/HomeController.cs e Northwind.Web/Views/Home/Spa.cshtml).
  6. Modificare il file _ViewStart.cshtml in modo MVC caricherà viste senza usare il file layout. cshtml di default (Northwind.Web/Views/_ViewStart.cshtml).
  7. Aggiornare i link di navigazione (menu) layout per abbinare i nuovi SPA-friendly URL (Northwind.Web/Views/Shared/_Layout.cshtml).

Dopo questi sette passi effettuati, la struttura del progetto di applicazione Web dovrebbe assomigliare Figura 1.

ASP.NET MVC Project Structure
Figura 1 ASP.NET MVC progetto struttura

Ti mostrerò come costruire un'impressionante SPA in ASP.NET MVC con le seguenti librerie JavaScript, disponibile via NuGet:

  • RequireJS (requirejs.org): Questo è un Java­caricatore di file e modulo di Script. RequireJS fornirà #include/importazione/richiedono API e la capacità di caricare annidati dipendenze con iniezione di dipendenza (DI). L'approccio di progettazione RequireJS utilizza la definizione di modulo asincrona (AMD) API JavaScript moduli, che consente di incapsulare le parti di codice in unità utile. Esso fornisce inoltre un modo intuitivo per fare riferimento ad altre unità di codice (moduli). RequireJS moduli anche seguono il modello di modulo (bit.ly/18byc2Q). Un'implementazione semplificata di questo modello utilizza funzioni JavaScript per l'incapsulamento. Vedrete questo modello in azione più tardi, come tutti i moduli di JavaScript saranno avvolto all'interno di una funzione di "definire" o "richiedono".
  • Chi ha familiarità con DI e inversione dei concetti di controllo (IoC) può pensare a questo come quadro DI lato client. Se è chiaro come il fango al momento, nessuna preoccupazione — che avrò presto in alcune illustrazioni codificati dove tutto questo avrà senso.
  • Testo plug-in per RequireJS (bit.ly/1cd8lTZ): Questo servirà da remoto caricare porzioni di HTML (viste) in SPA.
  • Entity Framework (bit.ly/1bKiZ9I): Questo è abbastanza auto-esplicativo, e perché il focus di questo articolo è su SPA, non voglio entrare troppo in Entity Framework. Tuttavia, se siete nuovi a questo, c'è un sacco di documentazione disponibile.
  • Kendo interfaccia utente Web (bit.ly/t4VkVp): Questo è un completo JavaScript /­quadro di HTML5 che ingloba Web UI widget, DataSources, modelli, il modello Model-View-ViewModel (MVVM), centri termali, styling e così via per contribuire a fornire un'applicazione reattiva e adattiva che sarà grande.

Creazione di infrastrutture SPA

Per mostrare come configurare l'infrastruttura SPA, in primo luogo spiegherò come creare il modulo RequireJS (config) (Northwind.Web/Scripts/app/main.js). Questo modulo sarà il punto di ingresso di start-up di app. Se hai creato un'applicazione console, si può pensare questo come punto di ingresso Main in Program.cs. Esso contiene essenzialmente la prima classe e il metodo che viene chiamato quando si avvia la SPA. Il file main.js fondamentalmente serve come manifesto della SPA ed è dove potrai definire dove sono tutte le cose nella SPA e le relative dipendenze, se presente. Il codice di configurazione RequireJS è mostrato Figura 2.

Figura 2 configurazione RequireJS

require.config({
  paths: {
    // Packages
    'jquery': '/scripts/jquery-2.0.3.min',
    'kendo': '/scripts/kendo/2013.3.1119/kendo.web.min',
    'text': '/scripts/text',
    'router': '/scripts/app/router'
  },
  shim : {
    'kendo' : ['jquery']
  },
  priority: ['text', 'router', 'app'],
  jquery: '2.0.3',
  waitSeconds: 30
});
require([
  'app'
], function (app) {
  app.initialize();
});

In Figura 2, la proprietà di percorsi contiene un elenco di dove si trovano tutti i moduli e i loro nomi. Shim è il nome di un modulo definito in precedenza. La proprietà spessore include eventuali dipendenze che possa avere il modulo. In questo caso, si carica un modulo denominato kendo ed ha una dipendenza su un modulo denominato jquery, quindi se un modulo richiede il modulo di kendo, vai avanti e caricare jQuery in primo luogo, perché jQuery è stato definito come una dipendenza per il modulo di kendo.

In Figura 2, il codice "richiedono ([], function(){})"verrà caricato nel modulo successivo, che è il modulo denominato app. Nota che ho volutamente dato nomi significativi ai moduli.

Quindi, come tuo SPA SA richiamare innanzitutto questo modulo? Ciò si configura nella prima pagina di atterraggio nella SPA con l'attributo principale di dati nel tag script riferimento per RequireJS. Ho specificato che esegue il modulo principale (main.js). RequireJS gestirà tutto il lavoro pesante caricare questo modulo; Devi solo dirgli quale modulo per caricare prima.

Hai due opzioni per viste SPA che saranno caricate in SPA: HTML standard (*. html) o pagine di MVC rasoio (*.cshtml) ASP.NET . Perché questo articolo è destinato agli sviluppatori .NET — e molte imprese hanno lato server librerie e Framework che vorrebbero continuare ad utilizzare nei loro punti di vista — che andrò con la seconda opzione di creazione di viste di rasoio.

Io iniziare aggiungendo una vista e il nome Spa.cshtml, come accennato in precedenza. Questa visione fondamentalmente caricherà la shell o tutto il codice HTML per il layout della SPA. Da questa vista, potrai caricare le altre viste (ad esempio, About.cshtml, Contact.cshtml, Index.cshtml e così via) come l'utente naviga attraverso le SPA, scambiando le opinioni che sostituire tutto l'HTML nel div "contenuto".

Creazione della pagina di atterraggio SPA (Layout) (Northwind.Web/Views/Spa.cshtml) perché la vista di Spa.cshtml è la SPA di pagina di destinazione dove tu potrai caricare in tutte le vostre opinioni, non ci sarà molta markup qui, diverso da quello di riferimento dei fogli di stile richiesto e RequireJS. Si noti l'attributo principale di dati nel codice seguente, che dice RequireJS quale modulo per caricare prima:

@{
  ViewBag.Title = "Spa";
  Layout = "~/Views/Shared/_Layout.cshtml";
}
<link href=
  "~/Content/kendo/2013.3.1119/kendo.common.min.css" 
  rel="stylesheet" />
<link href=
  "~/Content/kendo/2013.3.1119/kendo.bootstrap.min.css" 
  rel="stylesheet" />
<script src=
  "@Url.Content("~/scripts/require.js")"
  data-main="/scripts/app/main"></script>
<div id="app"></div>

L'aggiunta di un'azione per il Layout SPA (Northwind.Web/­Controllers/HomeController.cs) per creare e caricare la vista Spa.cshtml, aggiungere un'azione e visualizzazione:

public ActionResult Spa()
{
  return View();
}

Creare il modulo di domanda (Northwind.Web/Scripts/app/app.js) Ecco il modulo di domanda, responsabile per l'inizializzazione e il Router di interfaccia utente di Kendo di partenza:

define([
    'router'
  ], function (router) {
    var initialize = function() {
      router.start();
    };
    return {
      initialize: initialize
    };
  });

Creare il modulo Router (Northwind.Web/Scripts/app/router.js) è chiamato da JS. Se hai già familiarità con itinerari MVC ASP.NET , è la stessa nozione di qui. Questi sono i percorsi SPA per le visualizzazioni. Definire tutti gli itinerari per tutti la SPA viste così quando l'utente passa attraverso la SPA, il router interfaccia utente Kendo saprà cosa visualizzazioni per caricare in SPA. Vedere listato 1 nel download.

La classe di Kendo UI Router è responsabile per il monitoraggio dello stato dell'applicazione e navigando tra gli Stati dell'applicazione. Il router integra nella cronologia del browser utilizzando il frammento parte dell'URL (#page), rendendo l'applicazione gli Stati bookmarkable e collegabili. Quando viene fatto clic su un URL instradabile, il router interviene e racconta l'applicazione stessa rimettere in stato codificato in rotta. La definizione del percorso è una stringa che rappresenta un percorso utilizzato per identificare lo stato dell'applicazione che l'utente desidera vedere. Quando una definizione di route è corrisposto dal frammento di hash URL del browser, viene chiamato il gestore (vedere Figura 3).

Figura 3 definizioni di Route e gli URL corrispondenti registrati

Itinerario registrato (definizione) URL effettivo Full (Bookmarkable)
/ spa/home/localhost:25061/home/indice
/ home/indice localhost:25061/home/spa / #/ casa/indice/casa/informazioni
/ home/circa localhost:25061/casa/spa / #/ casa/circa/home/contatti
/ home/contatti localhost:25061/casa/spa / #/ home/contatto/cliente/indice
/ cliente/indice localhost:25061/casa/spa / #/ cliente/indice

Per quanto riguarda il widget di layout dell'interfaccia utente di Kendo, il suo nome parla da sé. Hai probabilmente familiarità con il layout ASP.NET Web Form MasterPage o MVC incluso nel progetto quando si crea una nuova applicazione Web di MVC ASP.NET . In questo progetto SPA, è situato presso il percorso Northwind.Web/Views/Shared/_Layout.cshtml. C'è poca differenza tra il layout dell'interfaccia utente di Kendo e layout MVC, tranne il layout dell'interfaccia utente di Kendo corre sul lato client. Proprio come il layout ha lavorato sul lato server, dove il runtime MVC vuoi scambiare il contenuto del layout con altri punti di vista, il Kendo UI layout funziona allo stesso modo esatto. Scambiare la vista (contenuto) del layout dell'interfaccia utente Kendo utilizzando il metodo showIn. Mostra contenuto (HTML) verrà inseriti nel div con ID "contenuto", che è stata passata nel layout dell'interfaccia utente di Kendo, quando è stato inizializzato. Dopo aver inizializzato il layout, lo poi rielabori dentro il div con ID "app", che è un div nella pagina di atterraggio (Northwind.Web/Views/Home/Spa.cshtml). Potrai rivedere che poco.

Il metodo di supporto loadView prende in un modello di visualizzazione, una vista e — se necessario — un callback da richiamare una volta che la visualizzazione e il modello di associazione si svolge. All'interno del metodo loadView, si sfrutta la libreria Kendo UI FX per migliorare esteticamente la UX aggiungendo qualche semplice animazione alla vista lo scambio processo. Questo avviene facendo scorrere la visualizzazione corrente caricata a sinistra, caricamento in remoto nella nuova vista e facendo scivolare la nuova vista caricata verso il centro. Ovviamente, si può facilmente cambiare questo a una varietà di diverse animazioni utilizzando la libreria di Kendo UI FX. Uno dei vantaggi principali di usando il layout dell'interfaccia utente di Kendo è indicato quando si richiama il metodo showIn per scambiare opinioni. Esso assicurerà la visualizzazione verrà scaricata, correttamente distrutto e rimosso dal DOM del browser, garantendo così la SPA può scalare ed è performante.

Modificare la vista di _ViewStart.cshtml (Northwind.Web/Views/­_ViewStart.cshtml) Ecco come configurare tutte le viste di non utilizzare il layout MVC ASP.NET per impostazione predefinita:

@{
  Layout = null;
}

A questo punto, dovrebbe funzionare la SPA. Quando si fa clic su uno dei collegamenti di navigazione del menu, si vede che il contenuto corrente è essere scambiato tramite AJAX grazie al router di Kendo UI e RequireJS.

Questi sette passi necessari per convertire un fresco ASP.NET Web Application in una SPA non sono troppo male, sono essi?

Ora che la SPA è fino e in esecuzione, potrai andare avanti e fare ciò che la maggior parte dei sviluppatori finirà facendo con un centro termale, che è l'aggiunta di alcuni creare, leggere, aggiornare ed eliminare funzionalità (CRUD).

L'aggiunta di funzionalità CRUD alla SPA

Ecco i passaggi chiavi necessari per aggiungere una griglia cliente per la SPA (e i file di codice del progetto correlato):

  • Aggiungere un controller MVC CustomerController (Northwind.Web/Controllers/CustomerController.cs).
  • Aggiungere un controller resto OData cliente Web API (Northwind.Web/Api/CustomerController.cs).
  • Aggiungere una griglia cliente (Northwind.Web/Views/­Customer/Index.cshtml).
  • Aggiungere un modulo di CustomerModel (Northwind.Web/Scripts/app/models/CustomerModel).
  • Aggiungere un modulo customerDatasource per la griglia del cliente (Northwind.Web/Scripts/app/datasources/customer­Datasource.js).
  • Aggiungere un modulo indexViewModel per la visualizzazione della griglia cliente (Northwind.Web/Scripts/app/viewModels/­indexViewModel.js).

La struttura in soluzione con Entity Framework che istituisce Figura 4 Mostra la struttura della soluzione, alta­tre progetti di illuminazione: Northwind.Data (1), Northwind.Entity (2) e Northwind.Web (3). Tratterò brevemente ciascuno, insieme a Entity Framework Power Tools.

  • Northwind.Data: Questo include tutto ciò che riguarda lo strumento di Entity Framework Object-Relational Mapping (ORM), per la persistenza.
  • Northwind.Entity: Questo include le entità del dominio, composto da classi POCO Plain Old CLR Object (). Questi sono tutti gli oggetti di dominio persistente-ignorante.
  • Northwind.Web: Ciò include il ASP.NET applicazione Web MVC 5 lo strato di presentazione, dove potrai costruire fuori la SPA con due precedentemente
  • menzionato librerie — UI di Kendo e RequireJS — e il resto dello stack lato server: Entity Framework, Web API e OData.
  • Entity Framework Utensili elettrici: Per creare tutte le entità POCO e mappature (database-prima), ho utilizzato il Entity Framework Power Tools dal team Entity Framework (bit.ly/1cdobhk). Dopo la generazione di codice, tutto quello che fatto qui è semplicemente copiare le entità in un progetto separato (Northwind.Entity) problematiche di separazione.

A Best-Practice Solution Structure
Struttura della soluzione di Best Practice figura 4

Nota: Lo script di installazione di Northwind SQL sia una copia di backup del database sono inclusi nel codice sorgente scaricabile sotto la cartella Northwind.Web/App_Data (bit.ly/1cph5qc).

Ora che la soluzione è configurata per accedere al database, andare avanti e scrivere la classe MVC CustomerController.cs per servire l'indice e modificare viste. Perché la responsabilità unica del controller è di servire una visualizzazione HTML per la SPA, il codice qui sarà minimo.

Creazione di MVC cliente Controller (Northwind.Web/­Controllers/CustomerController.cs) Ecco come creare il controller del cliente con le azioni dell'indice e modificare le visualizzazioni:

public class CustomerController : Controller
{
  public ActionResult Index()
  {
    return View();
  }
  public ActionResult Edit()
  {
    return View();
  }
}

Creare la vista con la griglia di clienti (Northwind.Web/­Views/Customers/Index.cshtml) Figura 5 viene illustrato come creare la vista con la griglia di clienti.

Se il markup in Figura 5 non è familiare, non ti preoccupare, è solo il markup di Kendo UI MVVM (HTML). Configura semplicemente un elemento HTML, in questo caso il div con ID della "griglia". Più tardi, quando si associa questa vista a un modello di visualizzazione con il quadro di Kendo UI MVVM, questo markup verrà convertito in widget UI di Kendo. Si può leggere di più su questo a bit.ly/1d2Bgfj.

Figura 5 cliente Grid View Markup con un Widget MVVM e associazioni eventi

<div class="demo-section">
  <div class="k-content" style="width: 100%">
    <div id="grid"
      data-role="grid"
      data-sortable="true"
      data-pageable="true"
      data-filterable="true"
      data-editable="inline"
      data-selectable="true"
      data-toolbar='[ { template: kendo.template($("#toolbar").html()) } ]'
      data-columns='[
        { field: "CustomerID", title: "ID", width: "75px" },
        { field: "CompanyName", title: "Company"},
        { field: "ContactName", title: "Contact" },
        { field: "ContactTitle", title: "Title" },
        { field: "Address" },
        { field: "City" },
        { field: "PostalCode" },
        { field: "Country" },
        { field: "Phone" },
        { field: "Fax" } ]'
      data-bind="source: dataSource, events:
        { change: onChange, dataBound: onDataBound }">
    </div>
    <style scoped>
    #grid .k-toolbar {
      padding: 15px;
    }
    .toolbar {
      float: right;
    }
    </style>
  </div>
</div>
<script type="text/x-kendo-template" id="toolbar">
  <div>
    <div class="toolbar">
      <span data-role="button" data-bind="click: edit">
        <span class="k-icon k-i-tick"></span>Edit</span>
      <span data-role="button" data-bind="click: destroy">
        <span class="k-icon k-i-tick"></span>Delete</span>
      <span data-role="button" data-bind="click: details">
        <span class="k-icon k-i-tick"></span>Edit Details</span>
    </div>
    <div class="toolbar" style="display:none">
      <span data-role="button" data-bind="click: save">
        <span class="k-icon k-i-tick"></span>Save</span>
      <span data-role="button" data-bind="click: cancel">
        <span class="k-icon k-i-tick"></span>Cancel</span>
    </div>
  </div>
</script>

Creazione di Controller di cliente API Web MVC (OData) (Northwind.Web/Api/CustomerController.cs) ora vi mostrerò come creare il controller MVC (OData) Web API cliente. OData è un protocollo di accesso ai dati per il Web che consente di eseguire query e modificare i set di dati attraverso operazioni CRUD in modo uniforme. Utilizzando ASP.NET Web API, è facile creare un endpoint OData. È possibile controllare quali operazioni OData sono esposti. È possibile ospitare più endpoint OData a fianco gli endpoint non OData. Avete il controllo completo sopra la tua logica di business modello, posteriore di dati e il livello dati. Figura 6 Mostra il codice per il controller del cliente Web API OData.

Il codice in Figura 6 crea solo un controller OData Web API per esporre i dati del cliente dal database Northwind. Una volta creato, è possibile eseguire il progetto e con strumenti come Fiddler (un debugger Web gratuito a fiddler2.com) o LINQPad, in realtà è possibile ricercare i dati dei clienti.

Figura 6 cliente Web API OData Controller

public class CustomerController : EntitySetController<Customer, string>
{
  private readonly NorthwindContext _northwindContext;
  public CustomerController()
  {
    _northwindContext = new NorthwindContext();
  }
  public override IQueryable<Customer> Get()
  {
    return _northwindContext.Customers;
  }
  protected override Customer GetEntityByKey(string key)
  {
    return _northwindContext.Customers.Find(key);
  }
  protected override Customer UpdateEntity(string key, Customer update)
  {
    _northwindContext.Customers.AddOrUpdate(update);
    _northwindContext.SaveChanges();
    return update;
  }
  public override void Delete(string key)
  {
    var customer = _northwindContext.Customers.Find(key);
    _northwindContext.Customers.Remove(customer);
    _northwindContext.SaveChanges();
  }
}

Configurazione ed esponendo OData dalla tabella Customer per la griglia (Northwind.Web/App_Start/WebApiConfig.cs) Figura 7 configura ed espone OData dalla tabella Customer per la griglia.

L'interrogazione OData Web API con LINQPad se non hai usato LINQPad (linqpad.net) ancora, si prega di aggiungere questo strumento al tuo toolkit per sviluppatori; un must-have è disponibile in una versione gratuita. Figura 8 illustrato LINQPad con una connessione per il Web API OData (localhost:2501 / odata), visualizzazione dei risultati della query LINQ , "Customer.Take (100)."

Figura 7 configurazione ASP.NET MVC Web API rotte per OData

public static void Register(HttpConfiguration config)
{
  // Web API configuration and services
  ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
  var customerEntitySetConfiguration =
    modelBuilder.EntitySet<Customer>("Customer");
  customerEntitySetConfiguration.EntityType.Ignore(t => t.Orders);
  customerEntitySetConfiguration.EntityType.Ignore(t =>
     t.CustomerDemographics);
  var model = modelBuilder.GetEdmModel();
  config.Routes.MapODataRoute("ODataRoute", "odata", model);
  config.EnableQuerySupport();
  // Web API routes
  config.MapHttpAttributeRoutes();
  config.Routes.MapHttpRoute(
    "DefaultApi", "api/{controller}/{id}",
    new {id = RouteParameter.Optional});
}

Querying the Customer Controller Web API OData Via a LINQPad Query
Figura 8 il Controller cliente l'esecuzione di query Web API OData tramite una Query LINQPad

Creazione del modello di cliente (osservabile) (Northwind.Web/­Scripts/app/models/customerModel.js) prossimo sta creando il modello cliente (Kendo UI osservabile). Si può pensare questo come un modello di dominio entità cliente lato client. Ho creato il modello cliente modo essa può essere facilmente riutilizzato da sia il cliente griglia e nella visualizzazione modifica. Il codice è riportato in Figura 9.

Figura 9 creando il modello cliente (Kendo UI osservabile)

define(['kendo'],
  function (kendo) {
    var customerModel = kendo.data.Model.define({
      id: "CustomerID",
      fields: {
        CustomerID: { type: "string", editable: false, nullable: false },
        CompanyName: { title: "Company", type: "string" },
        ContactName: { title: "Contact", type: "string" },
        ContactTitle: { title: "Title", type: "string" },
        Address: { type: "string" },
        City: { type: "string" },
        PostalCode: { type: "string" },
        Country: { type: "string" },
        Phone: { type: "string" },
        Fax: { type: "string" },
        State: { type: "string" }
      }
    });
    return customerModel;
  });

Creazione di un'origine dati per la griglia di clienti (Northwind.Web/Scripts/app/datasources/customersDatasource.js) se si ha familiarità con le origini dati da ASP.NET Web Form, il concetto è lo stesso qui, dove si crea un'origine dati per la griglia di clienti (Northwind.Web/Scripts/app/datasources/customersDatasource.js). Il Kendo UI DataSource (bit.ly/1d0Ycvd) componente è un'astrazione per uso locale (matrici di oggetti JavaScript) o remota dei dati (XML, JSON o JSONP). Completamente supporta le operazioni CRUD dati e fornisce il supporto locale e server-side per l'ordinamento, lo spostamento, filtro, raggruppamento e aggregati.

Creazione del modello di visualizzazione per la visualizzazione della griglia clienti se hai familiarità con MVVM da Windows Presentation Foundation (WPF) o Silverlight, questo è lo stesso concetto esatto, solo sul lato client (trovato in questo progetto in Northwind.Web/Scripts/ViewModels/­Customer/indexViewModel.cs). MVVM è un modello di separazione architettonico utilizzato per separare la visualizzazione e la logica dati e business. Vedrete un po ' che tutti i dati, la logica di business e così via è nel modello di visualizzazione e che la vista è puramente HTML (presentazione). Figura 10 viene illustrato il codice per il cliente, visualizzazione griglia.

Figura 10 il modello di visualizzazione griglia cliente

define(['kendo', 'customerDatasource'],
  function (kendo, customerDatasource) {
    var lastSelectedDataItem = null;
    var onClick = function (event, delegate) {
      event.preventDefault();
      var grid = $("#grid").data("kendoGrid");
      var selectedRow = grid.select();
      var dataItem = grid.dataItem(selectedRow);
      if (selectedRow.length > 0)
        delegate(grid, selectedRow, dataItem);
      else
        alert("Please select a row.");
      };
      var indexViewModel = new kendo.data.ObservableObject({
        save: function (event) {
          onClick(event, function (grid) {
            grid.saveRow();
            $(".toolbar").toggle();
          });
        },
        cancel: function (event) {
          onClick(event, function (grid) {
            grid.cancelRow();
            $(".toolbar").toggle();
          });
        },
        details: function (event) {
          onClick(event, function (grid, row, dataItem) {
            router.
navigate('/customer/edit/' + dataItem.CustomerID);
          });
        },
        edit: function (event) {
          onClick(event, function (grid, row) {
            grid.editRow(row);
            $(".toolbar").toggle();
          });
        },
        destroy: function (event) {
          onClick(event, function (grid, row, dataItem) {
            grid.dataSource.remove(dataItem);
            grid.dataSource.sync();
          });
        },
        onChange: function (arg) {
          var grid = arg.sender;
          lastSelectedDataItem = grid.dataItem(grid.select());
        },
        dataSource: customerDatasource,
        onDataBound: function (arg) {
          // Check if a row was selected
          if (lastSelectedDataItem == null) return;
          // Get all the rows     
          var view = this.dataSource.view();
          // Iterate through rows
          for (var i = 0; i < view.length; i++) {
          // Find row with the lastSelectedProduct
            if (view[i].CustomerID == lastSelectedDataItem.CustomerID) {
              // Get the grid
              var grid = arg.sender;
              // Set the selected row
              grid.select(grid.table.find("tr[data-uid='" + view[i].uid + "']"));
              break;
            }
          }
        },
      });
      return indexViewModel;
  });

Descriverò brevemente le varie componenti del codice in Figura 10:

  • onClick (supporto): Questo metodo è una funzione di supporto, che ottiene un'istanza di griglia cliente, la riga selezionata corrente e un modello JSON della rappresentazione del cliente per la riga selezionata.
  • salvare: Questo salva le modifiche quando si fa una modifica in linea di un cliente.
  • Annulla: Questo annulla fuori dalla modalità di modifica in linea.
  • dettagli: Questo si sposta la SPA per la modifica di vista del cliente, aggiungendo l'ID del cliente all'URL.
  • Edit: Questo comando attiva inline editing per il cliente selezionato corrente.
  • distruggere: Questo elimina l'attuale cliente selezionato.
  • onChange (evento): Questo viene generato ogni volta che un cliente è selezionato. Si memorizzata l'ultimo cliente selezionato in modo si può mantenere lo stato. Dopo l'esecuzione di eventuali aggiornamenti o navigare lontano dalla griglia cliente, quando navigare indietro alla griglia si riseleziona l'ultimo selezionato cliente.

Ora aggiungere moduli customerModel, indexViewModel e customersDatasource alla configurazione RequireJS (Northwind.Web/Scripts/app/main.js). Il codice è riportato in Figura 11.

Figura 11 RequireJS configurazione aggiunte

paths: {
  // Packages
  'jquery': '/scripts/jquery-2.0.3.min',
  'kendo': '/scripts/kendo/2013.3.1119/kendo.web.min',
  'text': '/scripts/text',
  'router': '/scripts/app/router',
  // Models
  'customerModel': '/scripts/app/models/customerModel',
  // View models
  'customer-indexViewModel': '/scripts/app/viewmodels/customer/indexViewModel',
  'customer-editViewModel': '/scripts/app/viewmodels/customer/editViewModel',
  // Data sources
  'customerDatasource': '/scripts/app/datasources/customerDatasource',
  // Utils
  'util': '/scripts/util'
}

Aggiungere una Route per la nuova visualizzazione griglia clienti nota che nel callback loadView (in Northwind.Web/Scripts/app/router.js) stai legando la barra degli strumenti della griglia dopo che è stato inizializzato e associazione MVVM ha avuto luogo. Questo è perché la prima volta che si legano la griglia, la barra degli strumenti non è inizializzato, perché esiste nella griglia. Quando la griglia è inizializzata tramite MVVM, verrà caricato nella barra degli strumenti dal modello Kendo UI. Quando viene caricato in griglia, si poi impegnare solo la barra degli strumenti per il vostro modello di visualizzazione così i pulsanti nella barra degli strumenti sono associati a Salva e Annulla metodi nel tuo modello di visualizzazione. Ecco il relativo codice per registrare la definizione di route per la visualizzazione di modifica del cliente:

router.route("/customer/index", function () {
  require(['customer-indexViewModel', 'text!/customer/index'],
    function (viewModel, view) {
      loadView(viewModel, view, function () {
        kendo.bind($("#grid").find(".k-grid-toolbar"), viewModel);
      });
    });
});

Ora avete una visualizzazione griglia di clienti completamente funzionale. Caricare fino localhost:25061/Home/Spa #/ cliente/indice (il numero di porta varierà probabilmente sulla tua macchina) in un browser e si vedrà Figura 12.

The Customer Grid View with MVVM Using the Index View Model
Figura 12 visualizzazione griglia cliente con MVVM utilizzando il modello di visualizzazione indice

Cablaggio Up the clienti Edit View Ecco i passaggi chiavi per aggiungere una visualizzazione di modifica del cliente alla SPA:

  • Creare una visualizzazione di modifica del cliente associata al modello cliente tramite MVVM (Northwind.Web/Views/Customer/Edit.cshtml).
  • Aggiungere un modulo di modifica visualizzazione modello per la visualizzazione di modifica del cliente (Northwind.Web/Scripts/app/viewModels/­editViewModel.js).
  • Aggiungere un modulo di supporto utilità per ottenere ID dall'URL (Northwind.Web/Scripts/app/util.js).

Perché si sta utilizzando il framework di interfaccia utente Kendo, vai avanti e stile tua visualizzazione modifica con gli stili dell'interfaccia utente di Kendo. Per ulteriori informazioni riguardo a bit.ly/1f3zWuC. Figura 13 illustrato il markup di visualizzazione di modifica con un widget MVVM e associazione degli eventi.

Figura 13 modifica vista Markup con un Widget MVVM e associazione eventi

<div class="demo-section">
  <div class="k-block" style="padding: 20px">
    <div class="k-block k-info-colored">
      <strong>Note: </strong>Please fill out all of the fields in this form.
</div>
    <div>
      <dl>
        <dt>
          <label for="companyName">Company Name:</label>
        </dt>
        <dd>
          <input id="companyName" type="text"
            data-bind="value: Customer.CompanyName" class="k-textbox" />
        </dd>
        <dt>
          <label for="contactName">Contact:</label>
        </dt>
        <dd>
          <input id="contactName" type="text"
            data-bind="value: Customer.ContactName" class="k-textbox" />
        </dd>
        <dt>
          <label for="title">Title:</label>
        </dt>
        <dd>
          <input id="title" type="text"
            data-bind="value: Customer.ContactTitle" class="k-textbox" />
        </dd>
        <dt>
          <label for="address">Address:</label>
        </dt>
        <dd>
          <input id="address" type="text"
            data-bind="value: Customer.Address" class="k-textbox" />
        </dd>
        <dt>
          <label for="city">City:</label>
        </dt>
        <dd>
          <input id="city" type="text"
            data-bind="value: Customer.City" class="k-textbox" />
        </dd>
        <dt>
          <label for="zip">Zip:</label>
        </dt>
        <dd>
          <input id="zip" type="text"
            data-bind="value: Customer.PostalCode" class="k-textbox" />
        </dd>
        <dt>
          <label for="country">Country:</label>
        </dt>
        <dd>
          <input id="country" type="text"
          data-bind="value: Customer.Country" class="k-textbox" />
        </dd>
        <dt>
          <label for="phone">Phone:</label>
        </dt>
        <dd>
          <input id="phone" type="text"
            data-bind="value: Customer.Phone" class="k-textbox" />
        </dd>
        <dt>
          <label for="fax">Fax:</label>
        </dt>
        <dd>
          <input id="fax" type="text"
            data-bind="value: Customer.Fax" class="k-textbox" />
        </dd>
      </dl>
      <button data-role="button"
        data-bind="click: saveCustomer"
        data-sprite-css-class="k-icon k-i-tick">Save</button>
      <button data-role="button" data-bind="click: cancel">Cancel</button>
      <style scoped>
        dd
        {
          margin: 0px 0px 20px 0px;
          width: 100%;
        }
        label
        {
          font-size: small;
          font-weight: normal;
        }
        .k-textbox
        {
          width: 100%;
        }
        .k-info-colored
        {
          padding: 10px;
          margin: 10px;
        }
      </style>
    </div>
  </div>
</div>

Creare un programma di utilità per ottenere l'ID del cliente dall'URL perché stai creando moduli concisi con confini puliti per creare una bella separazione delle preoccupazioni, illustrerò come creare un modulo Util dove risiederanno tutti i vostri aiutanti di utilità. Inizierò con un metodo di utilità che può recuperare l'ID del cliente nell'URL per il cliente DataSource (Northwind.Web/Scripts/app/datasources/customerDatasource.js), come mostrato Figura 14.

Figura 14 il modulo utilità

define([],
  function () {
    var util;
    util = {
      getId:
      function () {
        var array = window.location.href.split('/');
        var id = array[array.length - 1];
        return id;
      }
    };
    return util;
  });

Aggiungere il modello di visualizzazione modifica e Util moduli per la configurazione di RequireJS (Northwind.Web/Scripts/app/main.js) il codice in Figura 15 illustrato RequireJS aggiunte di configurazione per il cliente modifica moduli.

Figura 15 RequireJS configurazione aggiunte per il cliente modifica moduli

require.config({
  paths: {
    // Packages
    'jquery': '/scripts/jquery-2.0.3.min',
    'kendo': '/scripts/kendo/2013.3.1119/kendo.web.min',
    'text': '/scripts/text',
    'router': '/scripts/app/router',
    // Models
    'customerModel': '/scripts/app/models/customerModel',
    // View models
    'customer-indexViewModel': '/scripts/app/viewmodels/customer/indexViewModel',
    'customer-editViewModel': '/scripts/app/viewmodels/customer/editViewModel',
    // Data sources
    'customerDatasource': '/scripts/app/datasources/customerDatasource',
    // Utils
    'util': '/scripts/util'
    },
  shim : {
    'kendo' : ['jquery']
  },
  priority: ['text', 'router', 'app'],
  jquery: '2.0.3',
  waitSeconds: 30
  });
require([
  'app'
], function (app) {
  app.initialize();
});

Aggiungere il modello di visualizzazione modifica cliente (Northwind.Web/Scripts/app/viewModels/editViewModel.js) il codice in Figura 16 viene illustrato come aggiungere un modello di visualizzazione modifica cliente.

Figura 16 cliente modifica visualizzazione modello modulo per la visualizzazione del cliente

define(['customerDatasource', 'customerModel', 'util'],
  function (customerDatasource, customerModel, util) {
    var editViewModel = new kendo.data.ObservableObject({
      loadData: function () {
        var viewModel = new kendo.data.ObservableObject({
          saveCustomer: function (s) {
            customerDatasource.sync();
            customerDatasource.filter({});
            router.
navigate('/customer/index');
          },
          cancel: function (s) {
            customerDatasource.filter({});
            router.
navigate('/customer/index');
          }
        });
        customerDatasource.filter({
          field: "CustomerID",
          operator: "equals",
          value: util.getId()
        });
        customerDatasource.fetch(function () {
          console.log('editViewModel fetching');
          if (customerDatasource.view().length > 0) {
            viewModel.set("Customer", customerDatasource.at(0));
          } else
            viewModel.set("Customer", new customerModel());
        });
        return viewModel;
      },
    });
    return editViewModel;
  });

Descriverò brevemente le varie componenti del codice in Figura 16:

  • saveCustomer: Questo metodo è responsabile per salvare le modifiche sul cliente. Ripristina anche filtro di DataSource così la griglia verrà essere idratata con tutti i clienti.
  • Annulla: Questo metodo si sposterà la SPA torna alla visualizzazione griglia cliente. Ripristina anche filtro di DataSource modo che la griglia si essere idratata con tutti i clienti.
  • filtro: Questo richiama il metodo di filtro di origine dati e query per un cliente specifico dall'ID che è nell'URL.
  • fetch: Metodo fetch di DataSource viene richiamata dopo la configurazione del filtro. Nel callback dell'operazione di recupero, si imposta la proprietà del cliente del vostro modello di visualizzazione con il cliente che è stato restituito dal tuo recupero DataSource, che verrà utilizzato per associare alla tua visualizzazione di modifica del cliente.

Caricamento di un modulo, RequireJS codice all'interno del corpo del metodo di "definire" sarà solo ottenere richiamati una volta — che è quando RequireJS carica il modulo — così si espongono un metodo (loadData) nel vostro modello di visualizzazione modifica, così hai un meccanismo per caricare i dati dopo che è già stato caricato il modulo modifica visualizzazione modello (vedere questo in Northwind.Web/­Scripts/app/router.js).

Aggiungere una Route per il nuovo cliente vista di modifica (Northwind.Web/Scripts/app/router.js) Ecco il codice pertinente aggiungere il router:

router.route("/customer/edit/:id",
        function () {
    require(['customer-editViewModel',
          'text!/customer/edit'],
      function (viewModel, view) {
      loadView(viewModel.loadData(), view);
    });
  });

Si noti che, quando il modello di visualizzazione modifica cliente viene richiesto da RequireJS, sei in grado di recuperare il cliente chiamando il metodo loadData dal modello di visualizzazione. In questo modo sei in grado di caricare i dati corretti del cliente basati sull'ID che è nell'URL ogni volta la visualizzazione di modifica del cliente viene caricato. Un itinerario non deve essere solo una stringa hardcoded. Può inoltre contenere parametri, ad esempio un router server back-end (Ruby on Rails, ASP.NET MVC, Django e così via). Per fare questo, è il nome un segmento di rotta con un colon prima il nome della variabile che vuoi.

Ora carico il cliente modifica la visualizzazione nel browser è possibile (localhost:25061/Home/Spa #/ cliente/modifica/ANATR) e vedere la schermata raffigurata nella Figura 17.

The Customer Edit View
Figura 17 cliente vista di modifica

Nota: Anche se l'eliminazione (distruggere) funzionalità visualizzazione griglia del cliente è stata cablata fino, cliccando il pulsante "Elimina" nella barra degli strumenti (vedere Figura 18), vedrai un'eccezione, come mostrato Figura 19.

The Customer Grid View
Figura 18 visualizzazione griglia cliente

Expected Exception When Deleting a Customer Due to CustomerID Foreign Key Referential Integrity
Figura 19 prevede eccezioni quando si elimina un cliente dovuto CustomerID integrità referenziale chiave stranieri

Questa eccezione è di progettazione, perché la maggior parte dei Customer ID sono chiavi esterne in altre tabelle, ad esempio, ordini, fatture e così via. Si avrebbe a filo di un'eliminazione CSS che vuoi eliminare tutti i record da tutte le tabelle dove ID cliente è una chiave esterna. Anche se non sono in grado di cancellare nulla, ho voluto ancora mostrare i passaggi e il codice per la funzionalità di eliminazione.

Così là lo avete. Ho dimostrato come veloce e facile è di convertire un'applicazione Web di out-of-the-box ASP.NET in una SPA con RequireJS e interfaccia utente Kendo. Poi ha mostrato come è facile aggiungere funzionalità CRUD-come alle Terme.

Potete vedere una demo live del progetto d' bit.ly/1bkMAlK e si può vedere il sito del progetto CodePlex (e codice scaricabile) a easyspa.codeplex.com.

Codificazione felice!

Lungo Le è il principale architetto di app/dev .NET a CBRE Inc e Kendo/Telerik UI MVP. Egli trascorre la maggior parte del suo tempo, lo sviluppo di quadri e blocchi di applicazione, fornendo orientamenti per le migliori pratiche e modelli e standardizzazione dello stack di tecnologia di impresa. Egli ha lavorato con tecnologie Microsoft per più di 10 anni. Nel suo tempo libero, egli gode di blogging (blog.longle.net) e giocare a Call of Duty. Si può raggiungere e seguirlo su Twitter a twitter.com/LeLong37.

Grazie ai seguenti esperti tecnici per la revisione di questo articolo: Derick Bailey (Telerik) e Mike Wasson (Microsoft)