Préface: le blogueur a partagé quelques usages de base de KnockoutJS et bootstraptable auparavant. Ce sont toutes des applications de base et ils ne sont pas du tout encapsulés. Ils évitent simplement la valeur et l'attribution des contrôles HTML et sont loin de montrer l'exquisité de MVVM. Récemment, le projet prévoit d'utiliser officiellement KO, il a donc fait des emballages pour KO et bootstraptable, et il est partagé ici pour référence par les amis du parc. Pour les idées d'emballage, veuillez vous référer au Blog Park Master Xiao Qin. Si les amis du parc ont une meilleure façon, n'hésitez pas à en discuter.
Articles Knockoutjs Series:
Bootstraptable et knockoutjs se combinent pour atteindre la fonction d'ajout, de supprimer, de modifier et de vérifier [1]
Bootstraptable et knockoutjs se combinent pour atteindre la fonction d'ajout, de supprimer, de modifier et de vérifier [2]
1. Le premier ViewModel gère la requête
La mise en œuvre de la démo doit toujours poursuivre la fonction de gestion du département de la dernière fois. L'expansion suivante explique par le flux de données.
1. L'arrière-plan renvoie la mise en œuvre de ViewModel à la vue
public ActionResult index () {var Model = new {TableParams = new {url = "/ département / getDeartment", // pagesize = 2,}, urls = new {delete = "/ département / delete", edit = "/ département / edit", add = "/ département / edit",}, querycondition = new {name = "", des = "}; View (modèle);}Doute du code: le modèle renvoyé ici contient trois options
• TableParams: paramètres d'initialisation du tableau des pages. Étant donné que les paramètres par défaut sont définis dans JS, les paramètres définis ici sont des paramètres d'initialisation spécifiques à la page.
• URL: le chemin d'accès URL contenant la demande d'addition, de suppression et de modification.
• Querycondition: les conditions de requête de la page.
2. CODE DE PAGE CSHTML
Le code de page index.cshtml est le suivant:
@ {Layout = null;} <! Doctype html> <html> <adref> <meta name = "Viewport" contenu = "width = device-width" /> <itle> index </ title> <link href = "~ / contenu / bootstrap / csss / bootstrap.min.css" rel = "Styleet" /> <lien " href = "~ / contenu / bootstrap-table / bootstrap-table.min.css" rel = "Stylesheet" /> <script src = "~ / scripts / jQuery-1.9.1.min.js"> </ script> <script src = "~ / contenu / boootstrap / js / bootstrap.min.js"> </ script> src = "~ / contenu / bootstrap-table / bootstrap-table.min.js"> </ script> <script src = "~ / contenu / bootstrap-teable / locale / bootstrap-table-zh-cn.js"> </ script> <script src = "~ / scripts / knockout-3.4.0.min.js"> </ script> src = "~ / scripts / knockout / knockout-3.4.0.min.js"> </ script> <script src = "~ / scripts / knockout / extensions / knockout.mapping-latest.js"> </ script> <script src = "~ / scripts / extensions / knockout.index.js"> </cript> <prit> <prit> src = "~ / scripts / extensions / knockout.bootstraptable.js"> </ script> <script type = "text / javascript"> $ (function () {var data = @ html.raw (newtonsoft.json.jsonconvert.serializeobject (modèle)); ko.bindingViewModel (Data, Data, Document.getElementById ("div_index"));}); </cript> </ head> <body> <div id = "div_index" style = "padding: 0px; overflow-x: HIDDEN;"> <div> <div> CONDITIONS DE COURME </div> <div> <form ID = "FormSearch"> <div> <div> Department Name </ Label> Data-Bind = "Value: QueryCondition.name"> </ Div> <Belle> Department Description </Bel> <div> <Input Type = "Text" Data-Bind = "Value: QueryCondition.des"> </ Div> <div style = "Text-Align: Right;"> <Button Type = "Button" Data-BinD = "Click: ClearClick"> Clear </ Button> <Button " Type = "Button" Data-Bind = "Click: QueryClick"> Query </ Button> </div> </form> </ div> </div> <div id = "Toolbar"> <Button Data-Bind = "Click: AddClick" Type = "Button"> <span aria-hidden = "trueclick" Type = "Button> <Button Data-Bind =" Click: EDITCLICK " aria-hidden = "true"> </ span> modifier </ bouton> <bouton data-bind = "click: Deleteclick" type = "Button"> <span aria-hidden = "true"> </span> delete </ Button> </ div> <Table data-bind = "true"> </ th> <th datafough Nom </th> <th data-field = "Level"> Niveau du département </th> <th data-field = "DES"> Description </th> <th data-field = "Strecreatetime"> Temps de création </th> </tr> </ tead> </sable> </div> </ body> </html>Doute de code: comme l'article précédent, vous devez citer jQuery, bootstrap, bootstaptable, knockout et autres fichiers connexes. Voici les deux documents suivants:
• knockout.index.js: encapsule les propriétés et les liaisons des événements liées à la page de requête.
• knockout.bootstraptable.js: encapsule l'initialisation des méthodes bootstaptables et personnalise les méthodes de liaison à élimination directe.
Toutes les interactions de page ci-dessus sont encapsulées dans JS public, il n'est donc pas nécessaire d'écrire un grand nombre de codes en double tels que les éléments DOM pour obtenir des affectations, la liaison des événements, etc. sur la page. Il n'y a que les deux phrases ci-dessus de JS écrites sur cette page. N'est-ce pas très facile?
3. Encapsulation JS
Jetons un coup d'œil aux deux fichiers JS mentionnés ci-dessus, knockout.bootstable.js et knockout.index.js.
(1) knockout.bootstrapable.js
(Fonction ($) {// Ajoutez une méthode bootstraptableViewModel à ko.bootstraptableViewModel = function (options) {var that = this; this.default = {toolbar: '#toolbar', // quel conteneur pour le bouton d'outil QueryParams: fonction (param) {return {limite: param.limit (*) Pagination: true, // La pagination affiche-t-elle (*) sidepagination: "serveur", // Méthode de pagination: client Pagination du client, serveur de serveur Pagination (*) PageNumber: 1, // Initialise la première page à charger, la première page par défaut PageSize: 10, // le nombre de Rows enregistrés par page (*) PageList: [10, 25, 50, 100], // le numéro de page pour être sélectionné: [10, 25, 50, 100], // Numéro de Rows pour être sélectionné: [10, 25, 50, 100], // Numéro de Rows pour être sélectionné: [10, 25, 50, 100], // Numéro de Rows to Pagelist: [10, 25, 50, 100], (*) Méthode: «Get», recherche: true, // La recherche de table est-elle affichée? ClickToSelect: true, // Le clic pour sélectionner les lignes doit être activé showToggle: true,}; this.params = $ .Extend ({}, this.default, options || {}); // Obtenez l'enregistrement sélectionné this.getSelections = function () {var arres = that.refrable ("getSelection") return arrres;}; //fresh this.refres {that.bootstraptable ("rafraîchissement");};}; // ajouter ko liaison personnalisée ko.bindinghandlers.bootstraptable = {init: function (élément, Valueaccessor, AllbindingsAccessor, ViewModel) {// le oparam ici est la ViewModelvar BoundModelvar oviewModel = ValueAccessor (); $ (élément) .bootStrapable (oviewmodel.params); // ajouter une méthode bootstraptable au ViewModel oviewmodel.bootstraptable = function () {return $ ele.bootstraptable.apply ($ ele, arguments);}}, vue: function (élément, valgueaccessor, allBinDingsAsccess, vue, vue) {}};}) (jQuery);Doute du code: le code ci-dessus fait principalement deux choses
1. ViewModel personnalisé initialisé par bootstaptable.
2
Ajoutez des liaisons personnalisées KO.
Si les amis du parc ne comprennent pas l'utilisation de la liaison personnalisée, vous pouvez consulter les deux premiers articles de blog du blogueur (un) et (deux) pour une introduction détaillée.
(2) knockout.index.js
(fonction ($) {ko.bindingViewModel = fonction (data, bindElement) {var self = this; this.querycondition = ko.mapping.fromjs (data.querycondition); this.defaultQueryParams = {queryparams: function (param) {var params = self.Querycondition; params.limit = param.lit; params = self.Querycondition; Params.limit = param.lit; param.offset; return params;}}; var tableParams = $ .Extend ({}, this.defaultQueryParams, data.TableParams || {}); this.bootstraptable = new Ko.bootStrapableViewModel (tableParams); // clairement événement this.clearclick = function () {.aach ( Valeur) {// Clear if (typeof (valeur) == "fonction") {this (''); id = "mymodal" tabindex = "- 1" role = "dialog" aria-labelledBy = "mymodallabel"> </v> '); dialog.load (data.urls.edit, null, function () {}); $ ("body"). anness (dialog); dialog.modal (). On (' Lors de la fermeture de la boîte pop-up (ce clair comprend la compensation de la liaison et la compensation de l'événement d'enregistrement) ko.cleannode (document.getElementById ("Formedit")); Dialog.Remove (); self.bootstraptable.refresh ();});}; // edit event. (ArrrectedData.length <= 0 || ArrrectData.length> 1) {alert ("modifier une seule ligne à la fois"); return;} var dialog = $ ('<div id = "Mymodal" tabindex = "- 1" role = "dialog" aria-lAveLdBy = "MymodAlbel,"> </v>'); dialogle.Load. arrrectedData [0], function () {}); $ ("body"). APPEND (dialog); Dialog.Modal (). On ('Hidden.bs.Modal', function () {// Effacer la liaison lors de la fermeture de la boîte pop-up (ce clair inclut la compensation de la liaison et de la compensation de l'enregistrement événement) ko.cleannode (document.getElementById ("FormeDit")); Dialog.Remove (); self.bootstraptable.refresh ();});}; // supprimer l'événement this.deleteletSelection (); if (! ArrrectedData || ArrrectedData.Length <= 0) {alert ("Veuillez sélectionner au moins une ligne"); return;} $. Ajax ({url: data.urls.delete, type: "Post", ContentType: "application / json ', data: json.strifif {alert (status); self.bootstraptable.refresh ();}});}; ko.applybindings (self, bindement);};}) (jQuery);Doute du code: ce JS résume principalement les attributs et la liaison des événements des éléments de la page, et plusieurs endroits qui doivent être expliqués
• this.QueryCondition = ko.mapping.fromjs (data.QueryCondition): Le but de cette phrase est de convertir les conditions de requête passées de l'arrière-plan des données JSON aux attributs de surveillance. Ce n'est qu'en exécutant cette phrase que les attributs peuvent être surveillés et les éléments de page sont surveillés dans les deux sens.
• self.bootstraptable.refresh (): La signification de cette phrase consiste à actualiser les données du tableau. Il s'agit en fait de la méthode de rafraîchissement de bootstaptable qui s'appelle, mais le blogueur le résume simplement dans le fichier knockout.bootstraptable.js.
• Dialog.load (data.urls.edit, null, function () {}): Lors de l'ajout et de l'édition, la méthode de charge () de jQuery est utilisée. La fonction de cette méthode consiste à demander les éléments de page de cette URL et à exécuter le code JS de la page correspondante de l'URL. Cette méthode est très puissante pour se référer dynamiquement au fichier JS et exécuter le code dans le fichier JS.
Enfin, joignez le code correspondant à la méthode d'arrière-plan getDaStment ()
[Httpget] public jsonResult getDartment (int limite, int offset, nom de chaîne, string des) {var lstres = DepartmentModel.getData (); if (! String.isnullorempty (name)) {lstres = lstres.where (x => x.name.contains (name)). (! String.isnullOrempty (DES)) {lstres = lstres.where (x => x.des.conts (des)). Tolist ();} lstres.ForEach (x => {x.strcreatetime = x.createtime.tostring ("yyyyym-dd hh: mm: ss");}); lstres.skip (offset) .Take (limit) .tolist (), total = lstres.count}; return json (minerais, jsonrequestbehavior.allowget);}À ce stade, les fonctions de requête et de compensation de la page de requête peuvent être réalisées.
Avez-vous toujours une question: que se passe-t-il si nous devons personnaliser les événements de Bootstraptable? Vous ne pouvez pas être transmis via ViewModel en arrière-plan, non?
En effet, la méthode de l'événement JS ne peut pas être transmise à partir de l'arrière-plan, nous devons donc personnaliser la méthode de traitement de l'événement dans le front-end, par exemple, nous pouvons le faire:
<script type = "text / javascript"> $ (function () {var data = @ html.raw (newtonsoft.json.jsonconvert.serializeObject (modèle)); data.tableParams.onloadsuccess = function (data) {alert ("landsuccess event");}; ko.binDingViewModel (data, data, document.getElementById ("div_index"));}); </script>2. Obtenez le deuxième édition de ViewModel
L'un des anciens de vue ci-dessus gère les fonctions de requête et de suppression, mais l'ajout et l'édition nécessitent également la prise en charge d'un autre ViewModel. Jetons un coup d'œil à la mise en œuvre du package de l'édition.
1. Mise en œuvre de l'actionResult
Grâce à la requête de code ci-dessus, nous pouvons savoir que lorsque l'utilisateur clique sur Add et Modifier, une autre vue de vue sera demandée → / département / modifier. Jetons un coup d'œil à la mise en œuvre de la vue Edit
public ActionResult Edit (Modèle de département) {var oresmodel = new {editModel = modèle, urls = new {soumed = modèle.id == 0? "/ Département / add": "/ département / mise à jour"}}; return View (oresmodel);}Doute de code: Le code ci-dessus est très simple, qui consiste à renvoyer un ViewModel sur la page Affichage, contenant l'entité modifiée et l'URL soumise. La question de savoir si cette clé primaire entité existe est déterminé par le fait que le validation actuel soit une nouvelle entité ou une entité d'édition.
2. CODE CSHTML
Le code edit.cshtml est le suivant:
<form id = "Formedit"> <div role = "Document"> <div> <div> <Button Type = "Button" Data-Dismiss = "Modal" aria-Label = "Close"> <span Aria-Hidden = "True"> × </span> </siv> <h4 id = "Mymodallabel"> Opération </h4> </v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> <v> pour = "txt_departmentName"> Nom du département </ label> <entrée type = "text" name = "txt_departmentName" data-bind = "value: editmodel.name" placeholder = "Department Name"> </div> <div> <label for = "txt_departmentLevel"> Le niveau du département </vabe> <entrée = "Text" Text = "Txt_Develvel </ Label> <entrée =" Text " Data-Bind = "Value: EditModel.Level" Paceholder = "Department Level"> </ Div> <div> <label for = "txt_des"> Description </Bel> <Input Type = "Text" name = "TXT_DES" Data-Bind = "Value: EditModel.DES" Button "Data-Dism"> </v> <v> <Button Type = "Button" Button "Button" Modalin "> </ Div> <v> <Button Type =" Button "Button" Button = "Modali aria-hidden = "true"> </ span> ferme </ bouton> <bouton type = "soumi"> <span aria-hidden = "true"> </ span> Enregistrer </ bouton> </v> </div> </ form> <link href = "~ / contenu / bootstrapvalidator / cssheet" / scénario src = "~ / contenu / bootstrapvalidator / js / bootstrapvalidator.js"> </ script> <script src = "~ / scripts / extensions / knockout.edit.js"> </ script> <script type = "text / javascript"> $ (function () {var editData = @ Html.raw (newtonsoft.json.jsonconvert.serializeObject (modèle)); ko.bindingEditViewModel (editData, {});}); </ script>Doute de code: Étant donné que nous avons ajouté le composant de vérification BootstrapValidator, nous devons référencer le JS et le CSS pertinents. Ce fichier knockout.edit.js résume principalement les propriétés et la liaison des événements de la page d'édition. Jetons un coup d'œil au code d'implémentation de ce JS.
3. Encapsulation JS
knockout.edit.js code:
(fonction ($) {ko.bindingEditViewModel = fonction (data, validatorfields) {var that = {}; that.editmodel = ko.mapping.fromjs (data.editmodel); that.default = {message: 'Verification failli arrrectedData = ko.tojs (that.editmodel); $. ajax ({url: data.urls.soubmit, type: "post", contenu: 'application / json', data: json.stringify (arrrecteddata), succès: fonction (data, statut) {alert (status);}}); $ ("# mymodal"). modal ("hide");}}; {}); $ ('# formedit'). bootstrapvalidator (that.params); ko.applybindings (that, document.getElementByid ("Formedit"));};}) (jQuery);Doute de code: ce JS résume principalement les propriétés du modèle d'édition et la liaison des événements soumis. Étant donné que le composant de vérification bootstrapvalidator est utilisé, une soumission de formulaire est requise. En fait, la page ID ne doit pas apparaître dans JS public, tel que "Formedit" et "Mymodal" ci-dessus. Cela peut être passé comme un paramètre, qui doit être optimisé. Le paramètre Validator Fields représente le champ de vérification du composant de vérification. Si le formulaire ne nécessite pas de vérification, il est normal de passer un JSON vide ou non. Nous n'avons pas fait de vérification sur le terrain dans l'article ci-dessus. En fait, d'une manière générale, le tableau de base aura un ou plusieurs champs non vides, tels que la vérification non vide des noms de département. Le code sur la page edit.cshtml est modifié à ceci:
<form id = "Formedit"> <div role = "Document"> <div> <div> <Button Type = "Button" Data-Dismiss = "Modal" aria-Label = "Close"> <span Aria-Hidden = "True"> × </span> </button> <h4 id = "Mymodallabel"> Operation </h4> </v> <v> <évale Nom </ Label> <entrée type = "text" name = "name" data-bind = "value: editmodel.name" placeholder = "Department Name"> </ div> <div> <label for = "txt_departmentLevel"> DepartmentLevel </ Label> <entrée Type = "Text" Name = "Level" Data-Bind = "Value: EditModel.Level" placeholder="Departmentlevel"></div><div><label for="txt_des">Description</label><input type="text" name="Des" data-bind="value:editModel.Des" placeholder="Des"></div><div><button type="button" data-dismiss="modal"><span aria-hidden="true"></span>Close</button><button Type = "soumi"> <span aria-hidden = "true"> </span> Enregistrer </ bouton> </div> </div> </ form> <link href = "~ / contenu / bootstrapvalidator / css / bootstrapvalidator.css" rel = "Stylesheet" /> <> < src = "~ / contenu / bootstrapvalidator / js / bootstrapvalidator.js"> </ script> <script src = "~ / scripts / extensions / knockout.edit.js"> </ script> <script type = "text / javascript"> $ (function () {var editData = @ Html.raw (newtonsoft.json.jsonconvert.serializeObject (modèle)); ko.bindingEditViewModel (editData, {name: {validators: {notempty: {message: 'Le nom ne peut pas être vide!'}}}});Ensuite, il sera automatiquement vérifié lors de la soumission:
Remarque: Le nom d'attribut de vérification correspond à l'attribut de nom de la balise d'entrée, donc pour faire la vérification, cet attribut de nom doit être défini correctement.
Il est préférable de fixer une méthode d'arrière-plan pour ajouter, supprimer et modifier:
[Httppost] public JSonResult add (Department Odata) {DepartmentModel.Add (odata); return JSON (new {}, JSONRequestBehavior.Allowget);} [httppost] public JsonResult Update (Department Odata) {DepartmentModel.Update (odata); return json (new},,,}, JSONREQUESTBEHAVIOR.ALLOWGET);} [HTTPPOST] JSONRESULT PUBLIQUE DELETE (LIST <PARTEMENT> ODATA) {DepartmentModel.Delete (Odata); return json (new {}, jsonrequestbehavior.allowget);}À ce stade, l'effet de l'ajout, de la suppression, de la modification et de la vérification de la page entière est OK. Jetons un coup d'œil à l'effet brièvement:
3. Résumé
Ce qui précède résume simplement le service d'addition, de suppression, de modification et de recherche de Bootstraptable + KO, qui n'est qu'un package principal. Si vous devez les appliquer à votre projet, vous pouvez également avoir besoin de mesures d'optimisation simples, telles que:
1. S'il s'agit simplement d'un mode de vue d'une page, peut-il être préférable de l'écrire directement dans la page de vue sans le renvoyer de l'actionResult Action en arrière-plan, et cela enregistre le problème de la sérialisation et du passage des paramètres. Cela doit être optimisé.
2. L'ID de l'élément de page ne doit pas apparaître dans JS public. L'élément de page peut être transmis par des paramètres.
3. Ajouter et modifier les méthodes d'événements pour avoir beaucoup de code en double dans la zone contextuelle. La meilleure façon de faire cette partie est d'encapsuler la boîte contextuelle dans un composant distinct pour l'appeler, ce qui peut réduire la plupart du code JS.
4. S'il existe des éléments de boîte déroulants sélectionnés dans les conditions de requête et les propriétés éditées, vous devrez peut-être également encapsuler la source de données et d'autres attributs de la boîte déroulante. Cette partie est très courante. Une fois que le blogueur a trié la démo, ajoutez cette pièce.
Ce qui précède est la solution au bootstraptable + knockoutjs introduit par l'éditeur pour réaliser l'ajout, la suppression, la modification et la recherche (3) Les deux délai de vue ont terminé l'ajout, la suppression, la modification et la recherche. J'espère que ce sera utile à tout le monde. Si vous avez des questions, veuillez me laisser un message et l'éditeur répondra à tout le monde à temps. Merci beaucoup pour votre soutien au site Web Wulin.com!