Cet article a fait l'objet d'une traduction automatique.
Infrastructure RIA
Création d'applications Web orientées données avec ASP.NET MVC et Ext JS
Juan Carlos Carlos
Une application Internet riche (RIA) combine la facilité d'utilisation d'une application de bureau avec la flexibilité de déploiement sur le Web et de révision. Il existe deux approches principales pour la création de riches applications interactives. Tout d'abord, il existe des plug-ins de navigateur qui ordinateur hôte les environnements d'exécution tels que Flash, Java et Silverlight. Deuxièmement, il existe des bibliothèques d'extension JavaScript comme Dojo, Ext JS, jQuery, MooTools, Prototype et YUI. Chaque approche a ses avantages et des inconvénients.
Bibliothèques JavaScript sont un choix populaires pour la création de riches applications interactives, car JavaScript est pris en charge par tous les navigateurs principaux et n'est pas nécessaire d'installer un environnement de plug-in ou runtime. J'ai testé avec un autre des bibliothèques mentionnées — Ext JS — et j'ai découvert qu'il est un choix intéressant pour la mise en œuvre d'applications Web. Il est facile à implémenter et bien documentés et est compatible avec le sélénium pour le test. Ext JS fournit également des contrôles prédéfinis qui simplifient la création de l'interface utilisateur de votre application Web.
Malheureusement, la plupart des exemples de Ext JS sont illustrées avec PHP, Python et Ruby sur le code de Rails côté serveur. Mais cela ne signifie pas les développeurs qui utilisent les technologies Microsoft ne peut pas tirer parti de Ext JS. Il est difficile d'intégrer Ext JS avec le développement de Web Forms (en raison de la couche d'abstraction qui encapsule la nature de la requête-réponse du site Web afin de fournir un modèle basé sur le contrôle dynamique), vous pouvez utiliser ASP.Framework NET MVC, qui vous permet de tirer parti de Microsoft.NET Framework et JS Ext dans la même application.
Dans cet article, je vous propose le didacticiel, que je ne pouvais pas trouver, en progressant dans le développement d'une solution Web de réelles à l'aide d'ASP.NET MVC et JS Ext qui lit et écrit dans une base de données back-end.
Notions de base de formulaire ext JS
Pour utiliser Ext JS, vous devez tout d'abord le télécharger à partir de sencha.com. (J'ai utilisé la version 3.2.1, mais vous devez Attrapez la version la plus récente). Notez qu'une version open source gratuit de Ext JS est disponible pour les projets open source, les organisations à but non lucratif et formation. Pour d'autres usages, vous devrez peut-être acheter une licence. Reportez-vous à sencha.com/products/License.PHP pour plus d'informations.
Décompressez le fichier téléchargé sur un répertoire dans votre système de fichiers. Il contient tout ce dont vous avez besoin pour développer une solution Web à l'aide de JS Ext, notamment le fichier principal ext-all.js. (Il existe également une version debug pour aider à trouver plus facilement les erreurs.) Dépendances, documentation et exemples de code sont tous inclus dans le téléchargement.
Les dossiers requis pour un projet sont \adapters et \resources. Le dossier cartes permet l'utilisation d'autres bibliothèques à côté de Ext JS. Le dossier de ressources contient des dépendances, telles que les images et CSS.
Pour utiliser Ext JS correctement, vous devrez également inclure les trois références de fichier de clé dans vos pages :
ext-3.2.1/adapter/ext/ext-base.js
ext-3.2.1/ext-all.js
ext-3.2.1/resources/css/ext-all.css
Le fichier ext base.js contient les fonctionnalités principales de Ext JS. Les définitions de widget sont contenues dans ext all.js et ext all.css comprend des feuilles de style pour les widgets.
Commençons à l'aide de Ext JS dans une page HTML statique pour illustrer les concepts de base. Les lignes suivantes sont contenues dans la section head de la page et lier des fichiers nécessaires pour développer une solution Ext JS (J'ai également inclus le module de JavaScript avec des widgets exemple à partir du téléchargement Ext JS) :
<link rel="stylesheet" type="text/css"
href="ext-3.2.1/resources/css/ext-all.css" />
<script type="text/javascript" language="javascript"
src="ext-3.2.1/adapter/ext/ext-base.js"></script>
<script type="text/javascript" language="javascript"
src="ext-3.2.1/ext-all.js"></script>
<script type="text/javascript" language="javascript"
src="extjs-example.js"></script>
Dans le corps du fichier, insérer un élément div pour restituer le JS Ext principal formulaire :
<div id="frame">
</div>
Le fichier extjs-example.js donne des détails sur la construction des applications de Ext JS. Le modèle pour n'importe quelle application Ext JS utilise l'Ext. NS, instructions Ext.BLANK_IMAGE_URL et Ext.onReady :
Ext.ns('formextjs.tutorial');
Ext.BLANK_IMAGE_URL = 'ext-3.2.1/resources/images/default/s.gif';
formextjs.tutorial.FormTutorial = {
...
}
Ext.onReady(formextjs.tutorial.FormTutorial.init,
formextjs.tutorial.FormTutorial);
L'Ext. instruction de NS permet de vous pouvez organiser logiquement votre code dans un espace de noms, afin d'éviter les conflits de noms et des problèmes de portée.
L'instruction Ext.BLANK_IMAGE_URL est importante pour les widgets de rendu. Il a appelé l'image d'espacement (une image transparente de 1 x 1 pixel) et principalement utilisé pour générer des ainsi l'espace vide pour le placer les icônes et les séparateurs.
L'instruction Ext.onReady est la première méthode pour définir avec le code d'Ext JS. Cette méthode est appelée automatiquement dès que le DOM est complètement chargé, garantissant que chaque élément HTML que vous pouvez référencer est disponible lorsque le script s'exécute. Dans le cas d'extjs-example.js, voici le script lui-même :
formextjs.tutorial.FormTutorial = {
init: function () {
this.form = new Ext.FormPanel({
title: 'Getting started form',
renderTo: 'frame',
width: 400,
url: 'remoteurl',
defaults: { xtype: 'textfield' },
bodyStyle: 'padding: 10px',
html: 'This form is empty!'
});
}
}
Une instance de la classe Ext.FormPanel est créé en tant que conteneur pour les champs. La propriété renderTo pointe vers l'élément div où le formulaire sera restitué. La propriété par défaut Spécifie le type de composant par défaut du formulaire. La propriété url Spécifie l'URI pour envoyer la demande de l'écran. Enfin, la propriété html Spécifie le texte (avec une mise en forme HTML) en tant que la sortie par défaut.
Pour ajouter des champs, vous devez remplacer la propriété html avec la propriété items :
items: [ nameTextField, ageNumberField ]
Les deux premiers éléments à ajouter sont un champ de texte et un champ numérique :
var nameTextField = new Ext.form.TextField({
fieldLabel: 'Name',
emptyText: 'Please, enter a name',
name: 'name'
});
var ageNumberField = new Ext.form.NumberField({
fieldLabel: 'Age',
value: '25',
name: 'age'
});
Les propriétés requises sont : propriété fieldLabel (pour définir un message descriptif accompagnant le composant du formulaire) et la propriété name (pour définir le nom du paramètre de demande). La propriété emptyText définit le texte de filigrane que le champ affichera lorsqu'elle est vide. La propriété value est la valeur par défaut pour le contrôle.
Une autre façon de déclarer des contrôles est à la volée :
items: [
{ fieldLabel: 'Name', emptyText: 'Please, enter a name', name: 'name' },
{ xtype: 'numberfield', fieldLabel: 'Age', value: '25', name: 'age' }
]
Comme vous pouvez le voir, vous n'avez spécifier le type dans la mesure où elle est récupérée à partir des propriétés du formulaire par défaut pour le champ nom.
Je vais ajouter certains éléments supplémentaires au formulaire, ce qui finit par ressemble à la Figure 1.
La figure 1 le formulaire rempli
Jusqu'ici, vous avez créé un formulaire à l'aide de Ext JS pour extraire des données à partir de l'utilisateur. Maintenant, nous allons envoyer les données vers le serveur. Vous devrez ajouter un bouton permettant de gérer le processus de soumission et d'afficher le résultat à l'utilisateur, comme dans Figure 2.
La figure 2 boutons de formulaire
buttons: [{
text: 'Save',
handler: function () {
form.getForm().submit({
success: function (form, action) {
Ext.Msg.alert('Success', 'ok');
},
failure: function (form, action) {
Ext.Msg.alert('Failure', action.result.error);
}
});
}
},
{
text: 'Reset',
handler: function () {
form.getForm().reset();
}
}]
La propriété buttons permet à l'écran gérer toutes les actions possibles. Chaque bouton possède des propriétés name et gestionnaire. La propriété Gestionnaire contient la logique associée à l'action exécutée sur le bouton. Dans ce cas, il existe deux boutons dont les noms sont enregistrer et réinitialiser. Le Gestionnaire du bouton Enregistrer exécute une action d'envoi du formulaire et affiche un message indiquant la réussite ou l'échec. Le Gestionnaire de bouton de réinitialisation rétablit les valeurs des champs du formulaire.
La dernière — mais importantes — étape dans la création de formulaire est la validation. Afin de spécifier les champs obligatoires, nous devons définir la propriété allowBlank sur false et la propriété blankText pour une message d'erreur qui s'affiche lorsque la validation requise échoue. Par exemple, voici le champ nom du formulaire :
{ fieldLabel: 'Name', emptyText: 'Please, enter a name', name: 'name', allowBlank: false }
Lorsque vous exécutez l'application et cliquez sur le bouton Enregistrer sans entrer de données dans les champs nom et âge, vous recevez un message d'erreur et les champs obligatoires sont soulignés en rouge.
Pour personnaliser les messages d'erreur sur les champs, ajoutez la ligne suivante de code juste au-dessous de la fonction Ext.onReady :
Ext.QuickTips.Init() ;
Désormais, lorsque l'utilisateur déplace le pointeur de la souris sur le champ, une info-bulle avec un message affichant l'erreur est affichée.
Définir plusieurs règles de validation pour les champs tels que la spécification de la longueur minimale et maximale autorisée, le report de la validation de champ jusqu'à ce que l'envoi de formulaires et la création de validation fonctionnement pour les URL, les adresses de messagerie et les autres types de données. Vous pouvez voir les détails de cette validation dans le téléchargement de code.
Création de l'application Web
Maintenant, nous allons développer une solution Web en utilisant Ext JS et ASP.NET MVC. J'ai utilisé d'ASP.NET MVC 2, mais cette solution devrait être applicables à l'ASP.NET MVC 3 également. Le scénario, que je vais adresse consiste à ajouter un employé dans un système de gestion des ressources humaines.
La description de cas d'utilisation ajouter un employé se présente comme suit : un écran invite l'utilisateur à entrer des informations valides pour un nouvel employé comme identificateur d'employé, nom complet, adresse, âge, le salaire et le service. Le champ department est une liste de services, parmi lesquelles choisir.
La stratégie d'implémentation principale consiste à créer un JS Ext formulaire côté client, comme vous avez déjà vu — et ensuite traiter les données à l'aide d'ASP.NET MVC. La couche de persistance utilise LINQ pour représenter des entités métier et rendre persistantes des données au système de base de données. La base de données back-end est Microsoft SQL Server 2008.
Démarrez en ouvrant Visual Studio 2010 et en créant un nouveau projet avec l'ASP.Modèle Application Web de NET MVC 2.
Ensuite, créez le schéma de base de données. Pour cet exemple, le schéma contient deux entités : employé et service. La figure 3 montre comment j'ai créé les ressources humaines de base de données et les tables et les contraintes sous-jacent.
La figure 3 Création de la base de données de ressources humaines
create table department(
deptno varchar(20) primary key,
deptname varchar(50) not null,
location varchar(50)
);
create unique index undx_department_deptname on department(deptname);
insert into department
values('HQ-200','Headquarter-NY','New York');
insert into department
values('HR-200','Human Resources-NY','New York');
insert into department
values('OP-200','Operations-NY','New York');
insert into department
values('SL-200','Sales-NY','New York');
insert into department
values('HR-300','Human Resources-MD','Maryland');
insert into department
values('OP-300','Operations-MD','Maryland');
insert into department
values('SL-300','Sales-MD','Maryland');
create table employee(
empno varchar(20) primary key,
fullname varchar(50) not null,
address varchar(120),
age int,
salary numeric(8,2) not null,
deptno varchar(20) not null,
constraint fk_employee_department_belong_rltn foreign key(deptno)
references department(deptno)
);
create unique index undx_employee_fullname on employee(fullname);
Maintenant nous allons utiliser LINQ to SQL pour définir la structure des entités et le mécanisme de persistance. Commencez par créer une classe EmployeeRepository pour gérer la logique d'accès aux données dans la table employee. Dans ce cas, vous devez uniquement mettre en œuvre de l'opération de création :
public class EmployeeRepository {
private HumanResourcesDataContext _ctxHumanResources =
new HumanResourcesDataContext();
public void Create(employee employee) {
this._ctxHumanResources.employees.InsertOnSubmit(employee);
this._ctxHumanResources.SubmitChanges();
}
}
Vous devez également une classe DepartmentRepository pour gérer la logique d'accès aux données dans la table department. Là encore, dans ce cas simple il vous suffit de mettre en œuvre de l'opération de lecture afin de trouver une liste de services :
public class DepartmentRepository {
private HumanResourcesDataContext _ctxHumanResources =
new HumanResourcesDataContext();
public IQueryable<department> FindAll() {
return from dept in this._ctxHumanResources.departments
orderby dept.deptname
select dept;
}
}
Maintenant nous allons définir un autre élément important de l'architecture : le contrôleur. Pour définir un contrôleur, avec le bouton droit sur le dossier contrôleurs dans la fenêtre Explorateur de solutions et sélectionnez Ajouter | Contrôleur. J'ai utilisé HumanResourcesController en tant que le nom du contrôleur.
Couche de présentation ext JS
Passons maintenant à Ext JS et utiliser l'infrastructure pour générer la couche de présentation de l'application. Pour cette solution, vous devez uniquement importer ext all.js et les dossiers \adapter et \resources.
Accédez à la page Site.Master et ajoutez des références aux fichiers à l'intérieur de l'élément head, ainsi que d'un < asp : ContentPlaceHolder > Ext JSélément de balise en tant que conteneur du code JavaScript et CSS personnalisé pour chaque page, comme indiqué dans Figure 4.
La figure 4 Site.Master
<%@ Page Title="" Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent"
runat="server">
Index
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent"
runat="server">
<h2>Add a New Employee</h2>
<div id="employeeform"></div>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="Scripts"
runat="server">
<script type="text/javascript"
src="<%= Url.Content("~/Scripts/employee_form.js") %>">
</script>
</asp:Content>
Maintenant nous allons ajouter les autres éléments importants de l'architecture MVC : la vue. L'affichage présente le formulaire pour obtenir les données relatives à un employé. Accédez à HumanResourcesController, avec le bouton droit sur la méthode d'action Index et sélectionnez Ajouter une vue. Cliquez sur le bouton Ajouter dans la boîte de dialogue Ajouter une vue.
Pour implémenter le formulaire Ext JS créé précédemment dans cet article, vous devez ajouter un fichier JavaScript pour le répertoire de Scripts et une référence à ce fichier JavaScript dans la vue. Puis inclure la référence au fichier employee_form.js et ajoutez un élément div dans le mode de Index.aspx (voir Figure 5).
La figure 5 l'ajout de l'écran employé
< % @ Page Title = ""Language = « C# »MasterPageFile="~/Views/Shared/Site.Master"Inherits="System.Web.MVC.ViewPage"% >
< asp : Content ID = « content1 »ContentPlaceHolderID = « titlecontent »runat = « server » >Index < / asp : Content >
< asp : Content ID = « content2 »ContentPlaceHolderID = « maincontent »runat = « server » ><h2> Ajouter un nouvel employé </h2>< div id = « employeeform » >< / div. >< / asp : Content >
< asp : Content ID = « content3 »ContentPlaceHolderID = « Scripts »runat = « server » >< script type = « text/javascript »src = "< % = Url.Content("~/Scripts/employee_form.js") % >" ></script>< / asp : Content >
Ouvrez le fichier employee_form.js et ajoutez du code pour configurer le formulaire ExtJS et ses accessoires sous-jacent. La première étape consiste à définir une instance de la classe Ext.data.JsonStore pour obtenir une liste des départements :
var departmentStore = Ext.data.JsonStore nouveau ({url: « humanresources/départements », la racine: « départements », les champs: ['deptno', « deptname »]}) ;
La propriété url pointe vers la méthode d'action départements sur le contrôleur de HumanResourceController. Cette méthode est accessible par le verbe HTTP POST. La propriété de la racine est l'élément racine de la liste des départements. La propriété fields spécifie les champs de données. À présent définir le formulaire. Les propriétés sont autodescriptives :
var form = new Ext.FormPanel({
title: 'Add Employee Form',
renderTo: 'employeeform',
width: 400,
url: 'humanresources/addemployee',
defaults: { xtype: 'textfield' },
bodyStyle: 'padding: 10px',
Dans ce cas, la propriété url pointe vers la méthode d'action AddEmployee sur le contrôleur de HumanResourceController. Cette méthode est également accessible à l'aide de HTTP POST.
La propriété items fournit la liste des widgets représentant les champs du formulaire (Figure 6). Ici, le widget par défaut est un champ de texte (spécifié dans la propriété par défaut). Le premier champ est le numéro d'employé, qui est requis (spécifié par la propriété allowBlank). Le deuxième champ est le nom complet, qui est également un champ obligatoire. Le champ adresse est une zone de texte facultatif. Le champ d'expiration est un champ numérique facultatif. Le champ salary est un champ numérique requis. Et enfin, le champ de numéro de service est une chaîne d'identification est sélectionnée dans la liste des départements.
La figure 6 Widgets de champ de formulaire
items: [
{ fieldLabel: 'Employee ID', name: 'empno', allowBlank: false },
{ fieldLabel: 'Fullname', name: 'fullname', allowBlank: false },
{ xtype: 'textarea', fieldLabel: 'Address', name: 'address',
multiline: true },
{ xtype: 'numberfield', fieldLabel: 'Age', name: 'age' },
{ xtype: 'numberfield', fieldLabel: 'Salary', name: 'salary',
allowBlank: false },
{ xtype: 'combo', fieldLabel: 'Department', name: 'deptno',
store: departmentStore, hiddenName: 'deptno',
displayField: 'deptname', valueField: 'deptno', typeAhead: true,
mode: 'remote', forceSelection: true, triggerAction: 'all',
emptyText: 'Please, select a department...', editable: false }
],
Enfin, la propriété buttons définie pour gérer les actions sur le formulaire. Ce paramètre est configuré comme Figure 2, mais la propriété text a la valeur « Ajouter ».
Le fichier employee_form.js est maintenant terminé. (Je suis passé par le biais de la plupart des éléments du fichier ici. Consultez le code de téléchargement pour le code source complet pour ce fichier.)
Passons maintenant à HumanResourceController et implémenter les méthodes correspondantes de l'action, comme indiqué dans Figure 7.
La figure 7 HumanResourceController
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using HumanResources_ExtJS_ASPNETMVC.Models;
namespace HumanResources_ExtJSASPNETMVC.Models.BusinessObjects {
public class HumanResourcesController : Controller {
DepartmentRepository _repoDepartment = new DepartmentRepository();
EmployeeRepository _repoEmployee = new EmployeeRepository();
// GET: /HumanResources/
public ActionResult Index() {
return View();
}
// POST: /HumanResource/Departments
[HttpPost]
public ActionResult Departments() {
var arrDepartment = this._repoDepartment.FindAll();
var results = (new {
departments = arrDepartment
});
return Json(results);
}
// POST: /HumanResource/AddEmployee
[HttpPost]
public ActionResult AddEmployee(employee employee) {
string strResponse = String.Empty;
try {
this._repoEmployee.Create(employee);
strResponse = "{success: true}";
}
catch {
strResponse = "{success: false, error: \"An error occurred\"}";
}
return Content(strResponse);
}
}
}
C'est ça !
Exécutez maintenant la solution. Vous verrez la page Web affichée dans Figure 8. Entrer des données dans le formulaire, puis sur Ajouter. Vous verrez un message de confirmation. Vous verrez également la ligne insérée dans la table dbo.employee sur la base de données.
La figure 8 qui exécute l'Application
C'est vraiment tout est à la création d'un simple RIA. Selon les fonctionnalités que vous souhaitez tirer parti, une demande similaire pourrait être générée avec tous les autres cadres applicatifs JavaScript courants encore grâce à l'utilisation ASP.NET MVC. Vous pourriez facilement remplacer par Entity Framework pour la couche données et utilisez storage de bleu azur de Windows ou bleu azur de SQL comme magasin de données back-end. Ces blocs de construction simples que la création d'une base RIA orientée donnée rapidement et facilement.
Juan Carlos Olamendy est architecte senior, développeur et consultant. Il a été reconnu en tant que Microsoft Most Valuable Professional (MVP) et Oracle ACE plusieurs fois. Il est spécialiste en technologie certifiés Microsoft dans Windows Communication Foundation. Vous pouvez contacter Olamendy à johnx_olam@fastmail.
Merci aux experts techniques suivantes pour la révision de cet article : Scott hanselman et eilon Lipton