【问题标题】:Using razor views with jQuery validation with angularJS使用带有 AngularJS 的 jQuery 验证的剃刀视图
【发布时间】:2013-06-05 07:16:16
【问题描述】:

我在我的 MVC 应用程序中使用 AngularJS,并尝试使用两全其美的方法。我真的很喜欢在 MVC 中如何在视图模型中设置验证逻辑,并通过 jQuery 验证在 Razor 视图中轻松生成客户端验证。我使用 AngularJS 通过路由等来获取 SPA 行为,但是当我创建一个剃刀视图时,我用它来注入页面: <div data-ng-view="data-ng-view"></div>

然后 jQuery 验证停止工作,即使脚本文件是注入视图的页面上的引用。请参阅下面的剃刀观点:

@model BandViewModel
<div data-ng-controller="App.BandCreateCtrl">
    <form name="startBandForm">
        @Html.ValidationSummary(true)
        <br />
        @Html.LabelFor(m => m.Name)
        @Html.TextBoxFor(m => m.Name, new { data_ng_model = "band.Name" })
        @Html.ValidationMessageFor(m => m.Name)
        <br/>
        <input data-ng-disabled="startBandForm.$invalid" type="submit" data-ng-click="createBand(band)" value="Create"/>
    </form>
</div>

【问题讨论】:

    标签: asp.net-mvc razor angularjs jquery-validate


    【解决方案1】:

    对于仍在寻找解决此问题的方法的任何人,有一种简单的方法可以让它发挥作用。

        var currForm = $("#myForm");
    currForm.removeData("validator");
    currForm.removeData("unobtrusiveValidation");
    $.validator.unobtrusive.parse(currForm);
    currForm.validate();
    

    您可以将此代码放在 $viewContentLoaded 或与您的代码相关的其他位置。

    虽然我理解这里的一些视图不鼓励将 MVC 视图用作 Angular 代码的模板。我的原因是它不是一种以角度做事的自然方式,因此您可能会遇到这样的问题。但是,如果您从使用 MVC 视图作为模板中受益,那么它并不是一条通往地狱的道路。 IT 有效,也可以使您受益。我的项目中有 2 个用例,其中使用 MVC 视图很有意义。

    1. 我的项目实际上有一个要求,客户可以在某些字段上打开所需的验证,为此我使用 MVC 自定义数据注释验证器,它允许我在使用渲染视图时添加或删除数据注释一个单一的类,如果你要在 angular 中构建同样的灵活性,你将不得不编写更多的代码。因此,MVC 视图对我来说非常有用,因为自定义数据注释由 DisplayFor 和 EditorFor 助手触发
    2. 我们在国际化方面投入了大量资金,虽然 Angular 在其他方面做得很好,但国际化并不是它的强大套件(至少在撰写本文时)我仍然觉得 .RESX 在 MVC 中的国际化支持效果很好,并且已经存在很长时间了.这再次使用了 DisplayAttribute 的数据注释功能。

    TLDR:作为模板的 MVC 视图可能会给您带来一些意想不到的问题,但如果您真正使用 Microsoft 创建的数据注释管道的全部功能,那么它是值得的。

    希望将来有人想出一个 Angular HTML Helpers 库,这会简单得多。

    【讨论】:

    • 这其实用最简单的方式解决了问题。谢谢。
    【解决方案2】:

    您可以使用ngval 库。它将数据注释作为 angularjs 验证指令带到客户端。

    【讨论】:

      【解决方案3】:

      也许使用 Angular 进行验证并没有你想象的那么痛苦。使用几个自定义指令,您可以轻松获得与 Razor 非常接近的内容,其标记如下:

          <validated-input name=username display="User Name" ng-model=model.username required</validated-input>
      

      查看我的示例here 及其灵感here。目前只实现 required 和 number ,但自定义应该很容易。

      【讨论】:

        【解决方案4】:

        让我痛苦的是,到处我看过我们得到相同的答复:“HTML 应该只是一个模板”。也许吧,但我还没准备好将所有事情都委托给 JavaScript

        不要使用匿名对象来传递 HTML 属性,而是尝试使用字典

        @Html.TextBoxFor(m => m.Name, new Dictionary<string, object>(){{ "data_ng_model",  "band.Name" }})
        

        确保是

        Dictionary<string, object>
        

        不是

        Dictionary<string, string>
        

        否则构造函数会把它弄糊涂

        object HtmlAttribute
        

        虽然不那么漂亮......但它在大多数情况下都有效。

        最后,请记住,如果您在 jQuery 之后包含 AngularJS,那么它将使用 jQuery 作为选择器。

        【讨论】:

          【解决方案5】:

          首先,IMO 使用 Razor 渲染您的模板充其量是充满危险的。通常,您希望为您的页面和指令模板使用静态 HTML,然后检索数据并将其作为 AJAX 发布到您的 API。实际上,ASP.NET Web API 非常擅长这一点。如果您的底层模型具有验证功能,那么糟糕的 Web API 调用将引发异常,您可以在 $http 或 $resource 处理程序中捕获并显示给用户。将标准的 HTTP 表单帖子与 AngularJS 混合起来会很困难。

          为了实现你想要的,我认为有人(不是我)必须编写相当于jQuery Unobtrusive Validation library 的AngularJS,它本身正在使用jQuery Validate plugin。不是微不足道的。我个人认为不会很快出现插入式 Angular 验证,尤其是因为它更多地与标记有关,而与 JS 配置对象的关系较少。

          您可以在视图完成加载后使用the $viewContentLoaded event 重新初始化验证。但请不要。

          【讨论】:

          • 正如我所担心的......感谢您的出色回答:) 我会考虑您的反馈。
          • 我个人认为拥有基于 Razor 的视图可能是有益的。例如,您可以放置​​ @Html.TextBoxFor(m => m.Name),它将生成 AngularJS 授权的输入字段,其中包含所有 ng-model、ng-required 和许多其他易于手动执行的属性。当然,使用 ASP.NET MVC 可能有点过头了,但是您可以在 MVC 上下文之外使用带有 Razor 语法 (.cshtml) 的网页,该项目根本不会有任何对 ASP.NET MVC 的引用。以以下项目为例:github.com/kriasoft/angular-vsgithub.com/kriasoft/site-sdk
          • 我完全不同意。我在 Angular 中成功地使用了 Razor 模板非常,并且我的所有客户端模板都是强类型的,这是纯 HTML 页面无法获得的。诚然,OP 的模板不起作用,但如果您创建自己的 HtmlHelpers 来与 Angular 一起工作,那您就是黄金!
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多