在MVC剃刀C#和Javascript之间共享枚举 [英] Share enums between C# and Javascript in MVC Razor

查看:98
本文介绍了在MVC剃刀C#和Javascript之间共享枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看到了这个有用的答案添加常数为JavaScript文件中的问题,以便它可以用剃刀视图中使用:<一href=\"http://stackoverflow.com/questions/6217028/share-constants-between-c-sharp-and-javascript-in-mvc-razor\">Share在MVC剃刀 C#和Javascript之间的常量

I have seen this useful answer to a question for adding constants into a javascript file so it can be used with razor views: Share constants between C# and Javascript in MVC Razor

我希望能够做的只是定义枚举相同的,但我不知道如何在C#枚举转换成一个恒定的JavaScript。

I'd like to be able to do the same except define enums, but I'm not sure how to convert the C# Enum into a constant in javascript.

关闭的GetType(),似乎没有成为在恒定值,实际上得到的一种方式。

Off GetType(), there doesn't seem to be a way of actually getting at the constant value.

推荐答案

我以前使用的另一种方法是使用T4模板做这方面的工作。类似于 t4mvc 的工作方式,它可以是一个非常强大的工具,如果你知道如何挥动吧。

Another method I've used before is to use t4 templates to do this kind of work. Similar to the way that t4mvc works, which can be a very powerful tool if you know how to wield it.

这个想法是在您完成您的项目抓取并寻找一个枚举的t4template,当它发现一个,你会想模板改造它吐出基于C#code一些JavaScript。我第一次通过与T4Templates的工作,它爆炸了我的心思,不会有很多对他们重要的资源,但他们可以是例外(见t4mvc)

The idea is the in the t4template you crawl through your project and look for an enumerations, when it finds one, you'll want to template to transform it and spit out some javascript based on the C# code. The first time I worked with T4Templates through, it exploded my mind, and there aren't a lot of great resources for them, but they can be exceptional (see t4mvc)

使用以上在你链接到其他问题用控制器动作模板的优点在于,通过在t4的模板引擎生成的文件是输出被一个常规js文件,并且可以提供/缩小的像任何其他JavaScript文件而不是要求MVC的开销堆栈来满足要求。

The advantage of using templates over controller action used in the other question you linked to, is that the file generated by the t4 templating engine is the output is a regular js file and can be served/minified like any other JavaScript file, rather than requiring the overhead of the MVC stack to fulfill the request.

我大概可以挖出一个例子,如果你有兴趣。我可能没有在资源库中​​somwhere周围铺设。

I could probably dig up an example if you are interested. I probably have no laying around in a repository somwhere.

修改

所以我挖了一圈,发现一个例子,我编辑了一点从它原始的形式,并没有测试它,但你应该明白了吧。它有点长,所以我把它作为一个 GitHub的要点。但是,我在这里强调一些重要的块。

So I dug around and found an example, I edited it a bit from its original form and didn't test it but you should get the idea. Its a little long, so I put it up as a github gist. But I'll highlight some important chunks here.

首先, T4模板是内置到Visual Studio中的模板引擎,控制块写在C#(或VB如果你想)。我绝不发挥想象力的专家,而我不是自称是一个,但我会分享我所能。所以这些文件,一旦在Visual Studio项目中出现类似的其他code-背后类型的项目,在那里你可以扩展.TT项目,看到它背后的生成模板文件。

First, T4 templates are a templating engine built into Visual Studio, the control blocks are written in C# (or VB if you want). I am by no stretch of the imagination an expert, and am not claiming to be one, but I'll share what I can. So these files, once in a visual studio project appear similar to other "code-behind" types of items, where you can expand the .tt item and see the generated template file behind it.

所以让我们掏:

&LT;#@模板语言=C#V3.5调试=真hostspecific =真#&GT;

第一行设置为控制块的语言。正如你所看到的,我将使用C#。

The first line sets the language for the control blocks. As you can see I'm going to be using C#.

&LT;JS#@输出扩展=#&GT;

接下来,我设置生成的文件的扩展名。在这种情况下,我说,我想生成一个的.js 文件。所以,当我把这个模板到一个解决方案,让我们为 enum.tt ,当我运行它会创建一个名为 enum.js <文件模板/ code>。你不得不在所生成的文件(或文件)的控制。例如,t4mvc必须能够产生一串不同的文件(每个控制器)或产生单一 t4mvc.cs 文件的选项。

Next, i'm setting the extension of the generated file. In this case I'm saying that I want to generate a .js file. So when I place this template into a solution, lets as enum.tt, when I run the template it will create a file called enum.js. You do have control over the file (or files) that are generated. For example, t4mvc has the option to be able to generate a bunch of different files (one for each controller) or generate a single t4mvc.cs file.

接下来你会发现一大堆,我需要使用组件。一些更有趣的有以下几种:

Next you'll find a bunch of assemblies that I need to use. Some of the more interesting ones are the following:

<#@ assembly name="EnvDTE" #>
<#@ assembly name="EnvDTE80" #> 

同样,我不是专家,但你可以找到在MSDN网站上查看这些文档。这些提供了一些核心功能,能够访问/操纵Visual Studio解决方案。

Again, I'm not an expert, but you can find the documentation for these on the msdn site. These provide some core functionality to be able to access/manipulate the visual studio solution.

然后有一些相当无趣的进口。你会注意到,在控制块是由&LT;#..#&GT; (说实话,我真的不记得下一个字符的意义,它是的一会儿。)什么那不是包裹在一个控制模块将被直接写入到输出流。

Then there are some fairly uninteresting imports. You'll notice that the control blocks are delimited by <# .. #> (to be honest, I dont really remember the significance of the next character, its been a while.) Anything thats not wrapped in a control block will be written directly to the output stream.

这给我们带来实际的文件的开头将写入:

Which brings us to the start of actual file that will be written:

window.Enum = function() {
    this.__descriptions = [];
    this.__ids = []
    this.__last_value = 0;
}

window.Enum.prototype.add = function(name, val) {
    if(val == undefined) val = ++this.__last_value;
    this[name] = val;
    this[val] = name;
    this.__ids[val] = name;
    this.__descriptions[val] = name.replace(/ShowWithEllipses$/,"...").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/^\s+/,"");
    return this;
}

window.Enum.prototype.describe = function(val) { return this.__descriptions[val] };

下面我只是做一个简单的JavaScript执行枚举。没有声称它是最好的。但是,它是什么。 :)

Here i'm just making a trivial javascript Enum implementation. Not claiming it to be the best. But it is what it is. :)

<#
Prepare(this);
foreach(ProjectItem pi in FindProjectItemsIn(CurrentProject.ProjectItems.Item("Models"))) {
    DumpEnumerationsFrom(pi);
}
#>

然后我们到模板的肉。基本上,它看起来名为模型文件夹。和周围挖掘,试图找到任何枚举它可以找到。当它,它调用下面的方法:

Then we get to the meat of the template. Basically it looks in a folder called Models. And digs around and tries to find any enums it can find. When it does, it calls the following method:

void DumpEnumerationsFrom(ProjectItem file) {
    var enumerations = new List<CodeEnum>();
    FindEnum(file.FileCodeModel.CodeElements, enumerations);

    if(enumerations.Count > 0) TT.WriteLine("// {0}",file.Name);

    foreach(CodeEnum enumeration in enumerations) {
        TT.Write("window.Enum.{0}=(new Enum())", enumeration.Name);
        foreach(CodeElement ce in enumeration.Children) {
            var cv = ce as CodeVariable;
            if(cv == null) continue;
            TT.Write("\r\n\t.add(\"{0}\", {1})", cv.Name, cv.InitExpression ?? "undefined");
        }
        TT.WriteLine(";\r\n");
    }
}

在那里将产生类似下面的:

where it will generate something that looks like:

window.Enum.TheNameOfTheEnum = (new Enum()).add("Value1",1).add("Value2",2);

所以,最终的JS文件在C#项目中的枚举直接依据。

So the resulting JS file is based directly on the enumerations in your c# project.

有一定的局限性,虽然。一个枚举必须是一个文件,是在您的项目(不是在引用的库),至少使用该实施有可能是一个更聪明的方式来做到这一点。每次你改变你的枚举,你必须重新运行模板(右键单击它,选择运行自定义工具)。

There are some limitations though. One the enumeration has to be in a file that is in your project (not in a referenced library), at least using this implementation there might be a more clever way to do it. Every time you change your enums, you have to re-run the template (right click on it and select "Run Custom Tool").

但也有一定的优势,就像我之前提到的,生成的文件只是一个简单的js文件,这样可以组合并通过缩小运行。由于它只是一个文件,它可以在CDN托管,就像我前面提到的不需要命中了MVC堆到服务请求。

But there are some advantages, like I mentioned before, the resulting file is just a plain js file, so can be combined and run through minification. Because its just a file, it can be hosted on a CDN, and like I mentioned before doesn't require a hit to the MVC stack to serve the request.

无论如何,我并不是说其所有目的最好的主意,但它的下使用方式在我看来。但愿这可能有助于一些启发,给你研究的方向。

Anyway, I'm not saying its the best idea for all purposes, but it an under used approach in my opinion. Hopefully this may have helped shed some light and give you a direction of investigation.

这篇关于在MVC剃刀C#和Javascript之间共享枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆