Question

J'utilise editORTEMPlates pour des choses comme DateTime, les couleurs, etc. Mes formulaires, qui peuvent contenir pas mal de ces modèles, sont principalement chargés via Ajax comme vue partielle.

Plutôt que d'avoir un tas de scripts d'initialisation jQuery au bas de chaque modèle d'éditeur, existe-t-il une façon conceptuelle de le faire une seule fois par réponse? Disons que vous avez 10 cueilleurs de temps de date, sous une forme, il serait vraiment idiot de transmettre le même code d'initialisation 10 fois.

Placer le script d'initialisation sur le formulaire principal avec les pickers de 10 date serait efficace (ne fait certainement pas grand-chose pour garder le code isolé avec le modèle d'éditeur DateTime), mais il y a ensuite d'autres cas où vous voudrez peut-être avoir un sélecteur de date Sur un formulaire ou deux ou trois différents, et maintenant vous dupliquez ces scripts sur plusieurs vues dans votre code.

Alors, comment puis-je encore tirer parti des modèles d'éditeur de la bonne façon ici? Je pense que je cherche quelque chose comme -

EnsureThisScriptIsOutputOncePerThisResponse(<script>$('.datepicker').datepicker("insert lengthy config here");</script>)

Pour ajouter au bas du modèle d'éditeur qui fonctionne avec des vues partielles rendues via Ajax.

Était-ce utile?

La solution

Une chose que nous avons faite sur notre projet était d'avoir un fichier startup.js qui étend le modèle JavaScript discret en utilisant des attributs de données pour configurer des choses comme ça. Un exemple pour le nôtre est les boutons. Disons que j'avais le HTML suivant:

<input type='submit' data-button=true data-button-icon='ui-icon-check' value='approve' />

Le fichier de démarrage recherche des boutons quelque chose comme ceci:

function initializeButtons() {
    $("*[data-button=true]").each(function () {
        var $this = $(this);
        var initialized = $this.data('button-init');
        if (!initialized) {
            var options = {
                disabled: $this.data('button-disabled'),
                text: $this.data('button-text'),
                icons: {
                    primary: $this.data('button-icon-primary') || $this.data('button-icon'),
                    secondary: $this.data('button-icon-secondary')
                }
            };
            $this.button(options);
            $this.data('button-init', true);
        }
    });
}

$(document).ready(initializeButtons).ajaxSuccess(initializeButtons)

Cela rend le code d'initialisation de l'interface utilisateur jQuery commun beaucoup plus facile à gérer, et nous avons créé des extensions htmlhelper pour remplir facilement les attributs de données pour les éléments dont nous avons besoin.

Autres conseils

Alors, comment puis-je encore tirer parti des modèles d'éditeur de la bonne façon ici? Je pense que je cherche quelque chose comme - assurethisscriptisOutputoncepperThisResponse () pour ajouter au bas du modèle de l'éditeur.

Utilisant Cassette. Il s'agit de la bibliothèque qui vous permet de référencer les scripts et les feuilles de style de n'importe où - même à partir de vues partielles. Ensuite, il garantit l'ordre de référence du script et rend les scripts en garantissant ce script et ses références ne sortis qu'une seule fois et généralement en place unique en réponse.

Mise à jour:

Les scripts référencés pour AJAX peuvent être effectués comme suit

Dans DatePicker Editor Template - EditOremplates / DateTime.cshtml

@model DateTime?
@{
    Bundles.ReferenceScript("path to datepicker script. Script may reference jquery ui in its turn");
} 
//datepicker

Et dans le formulaire de conteneur DatePicker, rendent directement les scripts. Si ce n'est pas Ajax, cela aurait été fait dans la page de mise en page

@model ViewModelModelWithTenDates
@Bundles.RenderScripts() //will output distinc script references in order

//10 datepickers
@Html.EditorFor(model => model.FirstDate)

Vous pouvez utiliser livequery Plugin pour placer Ajouter le code d'initialisation dans un fichier .js externe et inclure le fichier dans votre _layout.cshtml.

$(".datepicker").livequery(function(){
    $(this).datepicker("insert lengthy config here");
});

J'utilise un attribut d'init le truc qui a besoin d'un script en cours d'exécution:

<input type="text" id="id" init="datepicker makereadonly" />

Cela indique que deux fonctions doivent être exécutées. Les exécuter est effectué dans Ajax-Complete qui est défini dans un fichier externe, notez qu'une fois qu'un élément est initialisé, l'attribut initialisé est défini. De cette façon, aucun script n'existe dans vos vues partielles.

var initFunctions = initFunctions || {};

initFunctions.datepicker = function(item) {
    $(item).datepicker();
};

initFunctions.readonly = function(item) {
    $(item).attr("disabled", "disabled");
};

$('body').ajaxComplete(function (e, xhr, settings) {
  var itemFunction = function (item) {
     var $this = $(item);
     var attr = $this.attr("init");
     var functions = attr.split(" ");
     for (var i = 0; i < functions.length; i++) {
        var funcName = functions[i];
        var func = initFunctions[funcName];
        if (func != undefined)
           func($this);
     }
     $this.attr("initialized", "");
  };

  items = $("[init]:not([initialized])");
  items.each(function (index, item) { itemFunction(item); });
});
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top