使用C#编写JavaScript

前端开发中JavaScript代码的维护总是让人头疼,特别是在富客户端应用中,必须要编写非常庞大的JavaScript代码,虽然JavaScript声称是面向对象的语言,但对于现代语言中常见的继承、强类型等的支持十分有限。如果我们能够将C#语言中的特性运用于JavaScript上,那么肯定将极大地提高JavaScript代码的维护性,提升开发效率。Saltarelle编译器就是这样的一个工具,他能将C#代码编译为JavaScript代码。

本文将展示如何使用Saltarelle编写JavaScript代码,我们将结合Saltarelle.jQuery和Saltarelle.Knockout库说明如何使用Saltarelle。本文使用Visual Studio 2012作为开发工具,通过NuGet获取相关扩展包。

1、首先新建一个空ASP.NET应用项目,此项目作为前端演示网站,项目名称为Web

2、添加一个类库项目,作为JavaScript脚本项目,该项目使用Saltarelle编译器自动生成脚本代码,项目名称为Scripts

3、选择Scripts项目,单击右键,选择“管理NuGet程序包”,在程序包管理界面,在上方搜索窗口中输入Saltarelle,搜索有关Saltarelle的包:

image

依次安装Saltarelle C# to JavaScript Compiler、Runtime library for the Saltarelle C# to JavaScript… 、Metadata required to use jQuery with Saltarelle …、Metadata required to use Knockout with Saltarelle …

4、Saltarelle包会更新Scripts项目,添加必要程序集引用,并修改项目使用Saltarelle编译器,由于Visual Studio 本身Bug,我们需要手动卸载并重新载入Scripts项目。此操作通过项目右键菜单完成。

5、修改Scripts项目类型:单击Scripts项目,右键选择属性,在输出类型中选择“控制台应用程序”,做此项修改的原因是让Saltarelle编译器自动调用Scripts的入口方法(即,Program的Main方法)

6、打开Properties文件夹下的AssemblyInfo.cs代码文件,注释掉一下ComVisible和Guid特性:

// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
//[assembly: ComVisible(false)]

// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
//[assembly: Guid("ecc66b86-53da-44b6-b83a-87b52da11e91")]

7、将Scripts项目中自动添加的Class1.cs代码文件修改为Program,并添加Main方法:

namespace Scripts
{
    class Program
    {
        static void Main()
        {

        }
    }
}

8、生成Scripts项目,完成后,我们可以在生成输出目录看到所生成的Scripts.js文件

接下来,我们演示如何使用jQuery:

jQuery中可以使用ready注册在页面载入完成后所要执行的程序,在Saltarelle.jQuery中,我们可通过OnDocumentReady方法来完成相同的功能,下面示例实现在页面载入完成后弹出提示框的功能:

1、在Program.cs中添加System.Html和jQueryApi命名空间

2、修改Main方法,代码如下:

using System.Html;
using jQueryApi;

namespace Scripts
{
    class Program
    {
        static void Main()
        {
            jQuery.OnDocumentReady(() =>
            {
                Window.Alert("Page is loaded");
            });
        }
    }
}

1、在Web项目中新建一个名称为Scripts的目录,该目录用于保存项目中的js文件

2、打开解决方案所在文件夹,将 packages\Saltarelle.Runtime.2.2.0下的mscorlib.js或mscorlib.min.js(压缩版)拷贝到Web项目的Scripts目录。

3、当然,由于我们使用了jQuery,所以也必须将jQuery库文件拷贝到Scripts目录下,在packages\Saltarelle.jQuery.1.9.0目录下也存在jQuery js文件

4、为了保证Scripts下的Scripts.js总是最新的,我们可以在Scripts项目的生成后事件中加复制命令将Scripts.js复制到Web项目的Scripts目录下:在Scripts项目属性中,选择生成事件,在后期生成事件中输入一下命令:

copy $(TargetDir)$(TargetName).js $(SolutionDir)Web\Scripts\$(TargetName).js

5、为了保证在生成Web项目时能自动更新Scripts.js脚本,可在Web项目中添加对Scripts项目的引用

6、下面在Web项目中添加一个名称为Index.html的HTML页面。在head标签内添加必要js文件的引用:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <script type="text/javascript" src="Scripts/mscorlib.min.js"></script>
    <script type="text/javascript" src="Scripts/jquery-1.9.1.js"></script>
    <script type="text/javascript" src="Scripts/Scripts.js"></script>
</head>
<body>

</body>
</html>

7、启动调试,打开页面后将弹出“Page is loaded”的提示。

Knockout是一个在js中实现MVVM模式的库,他能提供类似WPF中数据绑定的功能。

1、首先在Scripts项目中添加一个ViewModel类,代码如下:

using System;
using KnockoutApi;

namespace Scripts
{
    public class IndexViewModel
    {
        // 页面标题, 使用Observable表示该字段支持更改通知,当值改变时,它所关联的UI将自动更新
        public Observable<string> PageTitle = Knockout.Observable<string>();

        // 表示支持更改通知的数组
        public ObservableArray<LogItem> Logs = Knockout.ObservableArray<LogItem>();
    }

    public class LogItem
    {
        public string Level = String.Empty;

        public DateTime Time;

        public String Message = String.Empty;
    }
}

注意:有关如何使用Knockout实现MVVM模式,请参考Knockout官方网站

2、在Main方法中绑定ViewModel:

using System.Html;
using jQueryApi;
using KnockoutApi;

namespace Scripts
{
    class Program
    {
        static void Main()
        {
            jQuery.OnDocumentReady(() =>
            {
                Window.Alert("Page is loaded");

                IndexViewModel vm = new IndexViewModel();
                vm.PageTitle.Value = "未命名";

                Knockout.ApplyBindings(vm);
            });
        }
    }
}

3、将包中Knockout库文件拷贝到Web项目的Scripts目录中

4、在Index.html文件中添加对Knockout库js文件的引用

<script type="text/javascript" src="Scripts/mscorlib.min.js"></script>
    <script type="text/javascript" src="Scripts/jquery-1.9.1.js"></script>
    <script type="text/javascript" src="Scripts/knockout-2.2.0.min.js"></script>
    <script type="text/javascript" src="Scripts/Scripts.js"></script>

5、在Index.html使用ViewModel,实现数据绑定

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <script type="text/javascript" src="Scripts/mscorlib.min.js"></script>
    <script type="text/javascript" src="Scripts/jquery-1.9.1.js"></script>
    <script type="text/javascript" src="Scripts/knockout-2.2.0.min.js"></script>
    <script type="text/javascript" src="Scripts/Scripts.js"></script>
</head>
<body>
    <h1 data-bind="text:pageTitle"></h1>
    <button id="btnEdit">修改标题</button>
    <p>
        <strong>日志:</strong>
    </p>
    <ul data-bind="foreach:logs">
        <li>[<span data-bind="text:time"></span>]<span data-bind="text:level"></span><br /><span data-bind="text:message"></span></li>
    </ul>
</body>
</html>

需要注意的是,Salarelle编译器在生成js文件时,会自动对C#中的名称转换为js规范,故我们看到在html中,数据绑定时所使用的字段名称都是以小写字母开始。

6、在Html中有个“修改标题”的按钮,我们需要为此按钮增加事件处理函数,这里我们采用jQuery的click事件绑定方式,只需在Main方法、OnDocumentReady中增加以下代码:

jQuery.Select("#btnEdit").Click((s) =>
                {
                    vm.PageTitle.Value = "标题" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    vm.Logs.Value = vm.Logs.Value.Concat(new LogItem()
                    {
                        Level = "信息",
                        Time= DateTime.Now,
                        Message = "修改了标题"
                    });
                });

代码很简单,直接修改PageTitle,并向日志列表中添加一项日志。

7、启动调试,单击页面中按钮,执行效果

image

 

源代码下载

posted @ 2013-05-05 19:32  xfrog  阅读(5252)  评论(7编辑  收藏  举报