代码之家  ›  专栏  ›  技术社区  ›  Codebrain

在c中生成javascript并进行后续测试

  •  4
  • Codebrain  · 技术社区  · 14 年前

    我们目前正在开发一个asp.net mvc应用程序,该程序大量使用基于属性的元数据来驱动javascript的生成。

    下面是我们正在编写的方法类型的示例:

    function string GetJavascript<T>(string javascriptPresentationFunctionName,
                                     string inputId,
                                     T model)
    {
        return @"function updateFormInputs(value){
            $('#" + inputId + @"_SelectedItemState').val(value);
            $('#" + inputId + @"_Presentation').val(value);
         }
    
        function clearInputs(){
            " + helper.ClearHiddenInputs<T>(model) + @"
            updateFormInputs('');
        }
    
        function handleJson(json){
            clearInputs();
            " + helper.UpdateHiddenInputsWithJson<T>("json", model) + @"
            updateFormInputs(" + javascriptPresentationFunctionName + @"());
            " + model.GetCallBackFunctionForJavascript("json") + @"
        }";
    }
    

    此方法生成一些样板文件并将其交给其他返回字符串的各种方法。然后将整个批作为字符串返回并写入输出。

    我的问题是:

    1)除了使用大型字符串块之外,是否有更好的方法来完成此任务?

    我们已经考虑过使用StringBuilder或响应流,但它看起来相当“嘈杂”。使用string.format开始变得难以理解。

    2)如何对代码进行单元测试?仅仅做一个字符串比较来寻找字符串中的特定输出似乎有点业余。

    3)实际测试最终的javascript输出呢?

    谢谢你的意见!

    4 回复  |  直到 14 年前
        1
  •  1
  •   Dr. Wily's Apprentice    14 年前

    我通常尝试为大多数/所有javascript代码创建一个单独的.js文件。通常,我需要将common bahvior应用于许多由asp控件或服务器端代码动态创建的元素,因此我可能无法将所有内容都编码到.js文件中。

    我发现要在服务器上生成javascript的主要原因是,在页面呈现之前,您不会知道元素的id。因此,我试图尽可能地压缩依赖关系,以便生成尽可能少的javascript。例如,在传统的asp.net(而不是mvc)中,如果我呈现一组表单,比如在示例中,每个表单都有多个字段,那么我可能在代码后面有一些东西,比如:

    protected void FormRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        Control form = e.Item.FindControl("MyForm");
        ClientScript.RegisterStartupScript(this.GetType(), "prepareForm_" + form.ClientID, @"prepareForm('" + form.ClientID + "');", true);
    }
    

    单独的.js文件将包含prepareForm函数的定义,如下所示:

    // define a formPresenter "class" that encapsulates the behavior for a given form
    function formPresenter(formId) {
    
        this.setFirstName = function(value) {
            $("#" + formId + "_FirstName").val(value);
        }
    
        this.setLastName = function(value) {
            $("#" + formId + "_LastName").val(value);
        }
    
        // create other functions to handle more complicated logic
    
        // clear fields
        this.clearInputs = function() {
            this.setFirstName("");
            this.setLastName("");
            //...
        }
    
        // receive Json object
        this.handleJson = function(json) {
            this.clearInputs();
    
            // populate fields with json object
            this.setFirstName(json.FirstName);
            this.setLastName(json.LastName);
            //...
        }
    
        // "constructor" logic
    }
    
    function prepareForm(formId) {
        // create a new formPresenter object and shove it onto the specified element as the "presenter"
        document.getElementById(formId).presenter = new formPresenter(formId);
    }
    

    现在几乎所有的实际逻辑都在它自己的.js文件中,应该更容易维护。如果需要访问给定窗体的form presenter对象,则只需获取对formid参数所引用的任何元素的引用并访问presenter变量:

    "document.getElementById(" + form.ClientID + ").presenter.handleJson(json);"
    

    注意:自从我使用jquery以来,我发现甚至不需要包含服务器生成的任何javascript。通常,我可以通过查找一个特定的css类名(或类似的东西)来找到所需的元素,并执行所需的任何设置/初始化。

        2
  •  2
  •   Dave Van den Eynde    14 年前

    我们创建了一个库,专门用于将javascript嵌入到我们的c代码中,并使其成为开源的。

    看一看 Adam.JSGenerator .

        3
  •  1
  •   Edgar    14 年前

    我们在我们的项目中也做了大量的js生成,我们使用stringbuilder来完成它。

    StringBuilder sb = new StringBuilder();
    
    sb.Append("some javascript stuff")
      .Append("some more")
      .AppendFormat("formatted stuff {0}", "here");
    
    return sb.ToString();
    

    这不漂亮,但没有解决办法。

    关于测试,我们实际上不会对生成的代码进行任何单元测试。在发布之前,人们会去测试所有的特性,以确保它们按预期工作。

        4
  •  1
  •   Adam Gent    14 年前

    如果不关心超级重复的性能,可以使用模板语言生成javascript。

    然后,对于单元测试,您只需使用适当的绑定/变量填充模板,然后通过像rhino这样的javascript计算器或任何.net等价物运行它,以便至少测试语法(如果不是实际的js代码)。

    除此之外,我还对生成类似javascript的软件的设计提出了严重的质疑。看起来您正在使用jquery,但是直接引用$,这可能会导致一些问题。

    如果编译器生成javascript是一回事(ala gwt),但我会尽可能地将客户端js代码与.net代码分开(更不用说您的.net代码看起来像服务器端js所说的混乱)。

    这种将客户端垃圾与服务器分离的流行设计被称为sofea。我让你搜索一下。