Est-il possible d'accéder à une propriété Model dans un fichier Javascript externe?
par exemple. Dans le fichier "somescript.js"
var currency = '@Model.Currency';
alert(currency);
À mon avis
<script src="../../Scripts/somescript.js" type="text/javascript">
Cela ne semble pas fonctionner, mais si je mets le javascript directement dans la vue à l'intérieur des balises de script, cela fonctionne-t-il? Cela signifie qu'il faut mettre le code dans la page tout le temps au lieu de charger le fichier de script externe comme ceci:
@model MyModel;
<script lang=, type=>
var currency = '@Model.Currency';
alert(currency);
</script>
Y a-t-il un moyen de contourner cela?
Il n'y a aucun moyen d'implémenter le code MVC/Razor dans les fichiers JS.
Vous devez définir des données variables dans votre code HTML (dans les fichiers .cshtml). Ce concept est OK et ne viole pas la séparation des problèmes (code HTML généré par le serveur par rapport au code de script client) car, si vous y réfléchissez, ces valeurs de variable sont: une préoccupation de serveur.
Jetez un coup d’œil à cette solution de contournement (partielle mais agréable): Utilisation du fichier Javascript intégré dans un fichier Javascript dans le cadre MVC
J'ai abordé ce problème en utilisant des attributs de données, ainsi que jQuery. Cela rend le code très lisible, et sans la nécessité de vues partielles ou de l'exécution de javascript statique à l'aide d'un ViewEngine. Le fichier JavaScript est entièrement statique et sera mis en cache normalement.
Index.cshtml:
@model Namespace.ViewModels.HomeIndexViewModel
<h2>
Index
</h2>
@section scripts
{
<script id="Index.js" src="~/Path/To/Index.js"
data-action-url="@Url.Action("GridData")"
data-relative-url="@Url.Content("~/Content/Images/background.png")"
data-sort-by="@Model.SortBy
data-sort-order="@Model.SortOrder
data-page="@ViewData["Page"]"
data-rows="@ViewData["Rows"]"></script>
}
Index.js:
jQuery(document).ready(function ($) {
// import all the variables from the model
var $vars = $('#Index\\.js').data();
alert($vars.page);
alert($vars.actionUrl); // Note: hyphenated names become camelCased
});
_Layout.cshtml (facultatif, mais bonne habitude):
<body>
<!-- html content here. scripts go to bottom of body -->
@Scripts.Render("~/bundles/js")
@RenderSection("scripts", required: false)
</body>
Ce que vous pouvez faire est de passer les étiquettes de rasoir en tant que variable.
Dans rasoir Fichier>
var currency = '@Model.Currency';
doAlert(currency);
dans le fichier JS>
function doAlert(curr){
alert(curr);
}
Ce que j’ai fait, c’est de créer un objet js à l’aide du modèle d’appel de méthode, puis de l’appeler à partir du fichier js externe. Comme js utilise des variables globales, je l’encapsule pour éviter tout conflit avec les autres bibliothèques js. Exemple: Dans la vue
@section scripts{
<script>
var thisPage = {
variableOne: '@Model.One',
someAjaxUrl: function () { return '@Url.Action("ActionName", "ControllerName")'; }
};
</script>
@Scripts.Render("~/Scripts/PathToExternalScriptFile.js")
}
Désormais, à l'intérieur de la page externe, vous pouvez obtenir les données avec une étendue protégée pour vous assurer qu'elles ne sont pas en conflit avec d'autres variables globales dans js.
console.log('VariableOne = ' + thisPage.variableOne);
console.log('Some URL = ' + thisPage.someAjaxUrl());
Vous pouvez aussi l'envelopper à l'intérieur d'un module dans le fichier externe pour le rendre encore plus résistant aux chocs. Exemple:
$(function () {
MyHelperModule.init(thisPage || {});
});
var MyHelperModule = (function () {
var _helperName = 'MyHelperModule';
// default values
var _settings = { debug: false, timeout:10000, intervalRate:60000};
//initialize the module
var _init = function (settings) {
// combine/replace with (thisPage/settings) passed in
_settings = $.extend(_settings, settings);
// will only display if thisPage has a debug var set to true
_write('*** DEBUGGER ENABLED ***');
// do some setup stuff
// Example to set up interval
setInterval(
function () { _someCheck(); }
, _settings.intervalRate
);
return this; // allow for chaining of calls to helper
};
// sends info to console for module
var _write = function (text, always) {
if (always !== undefined && always === true || _settings.debug === true) {
console.log(moment(new Date()).format() + ' ~ ' + _helperName + ': ' + text);
}
};
// makes the request
var _someCheck = function () {
// if needed values are in settings
if (typeof _settings.someAjaxUrl === 'function'
&& _settings.variableOne !== undefined) {
$.ajax({
dataType: 'json'
, url: _settings.someAjaxUrl()
, data: {
varOne: _settings.variableOne
}
, timeout: _settings.timeout
}).done(function (data) {
// do stuff
_write('Done');
}).fail(function (jqxhr, textStatus, error) {
_write('Fail: [' + jqxhr.status + ']', true);
}).always(function () {
_write('Always');
});
} else {// if any of the page settings don't exist
_write('The module settings do not hold all required variables....', true);
}
};
// Public calls
return {
init: _init
};
})();
Essayez JavaScriptModel ( http://jsm.codeplex.com ):
Ajoutez simplement le code suivant à votre action de contrôleur:
this.AddJavaScriptVariable("Currency", Currency);
Vous pouvez maintenant accéder à la variable "Currency" en JavaScript.
Si cette variable doit être disponible sur le site du trou, placez-la dans un filtre. Vous trouverez un exemple d'utilisation de JavaScriptModel à partir d'un filtre dans la documentation.
Vous pouvez toujours essayer RazorJs. Il est pratiquement impossible de ne pas utiliser un modèle dans vos fichiers js RazorJs