13

我在 VS2012 上获得了 DurandalJS StarterKit 模板......一切都很好......

但在某些观点中,我需要做这样的事情:

@if (Roles.IsUserInRole("Administrators"))
{
   <p>Test</p>
}

但是,对于 durandal,我所有的视图都是“.html”文件......是否可以使用“.cshtml”文件来访问类似的信息?

或者有没有其他方法可以用 durandal 做到这一点?

初级

4

8 回答 8

32

我这样做是这样的:

  1. 为 Durandal 视图创建一个通用控制器:

    public class DurandalViewController : Controller
    {
      //
      // GET: /App/views/{viewName}.html
      [HttpGet]
      public ActionResult Get(string viewName)
      {
        return View("~/App/views/" + viewName + ".cshtml");
      }
    }
    
  2. 注册路线:

    routes.MapRoute(
        name: "Durandal App Views",
        url: "App/views/{viewName}.html",
        defaults: new { controller = "DurandalView", action = "Get" }
    );
    
  3. 将 Views/web.config 复制到 /App/views/web.config(以便 Razor 视图在此位置工作)。

这让我可以使用正常的 Durandal 约定(甚至是视图的 html 扩展名),并将 durandal 视图作为 cshtml 文件放在其正常位置,而无需添加任何更多的服务器代码。

如果您还有静态 html 视图,您也可以将 cshtml 视图放在子文件夹中或使用普通的 MVC /Views 文件夹。

于 2013-03-26T12:07:44.493 回答
8

我不建议将 ASP.NET MVC 与 Durandal 一起使用。

您可能想要做的是使用独立于 ASP.NET MVC 存在的 Razor 视图引擎(以获得编译器、强类型等的好处)。仅用于数据 I/O 的 WebAPI 就足以非常有效地创建 Durandal.js 应用程序。

如果您有兴趣将Razor/CSHTML 与 Durandal 和 Knockout 一起使用,那么有一个名为FluentKnockoutHelpers的开源选项可能正是您正在寻找的。它提供了 ASP.NET MVC 的许多“不错”部分,允许您使用 Durandal 和 Knockout 的强大功能,几乎没有失败。

简而言之,它提供了一系列特性,使得进行 Durandal/Knockout 开发就像 ASP.NET MVC 一样简单。(您只需为大多数功能提供您的 JavaScript 模型所基于的 C# 类型。)您只需为复杂的情况编写 JavaScript 和未编译的标记,这是不可避免的,与 MVC 没有什么不同!(除了在 MVC 中,您的代码也很可能最终也会成为一个大的 jQuery 混乱,这就是您首先使用 Durandal/Knockout 的原因!)

特征:

  • 使用类似于 ASP.NET MVC 的强类型、流畅的 lambda 表达式助手轻松生成 Knockout 语法
  • 丰富的智能感知和编译器支持语法生成
  • 流利的语法使创建自定义助手或扩展内置内容变得轻而易举
  • OSS 替代 ASP.NET MVC 助手:随意添加社区中每个人都可以使用的可选功能
  • 只需几行代码,即可针对所有当前/未来的应用程序类型和更改轻松地提供基于 .NET 类型和 DataAnnotations 的验证
  • 客户端 JavaScript 对象工厂(基于 C# 类型)在例如列表中创建新项目,零麻烦或服务器流量

没有 FluentKnockoutHelpers 的示例

<div class="control-group">
    <label for="FirstName" class="control-label">
        First Name
    </label>
    <div class="controls">
        <input type="text" data-bind="value: person.FirstName" id="FirstName" />
    </div>
</div>
<div class="control-group">
    <label for="LastName" class="control-label">
        Last Name
    </label>
    <div class="controls">
        <input type="text" data-bind="value: person.LastName" id="LastName" />
    </div>
</div>
<h2>
    Hello,
    <!-- ko text: person.FirstName --><!-- /ko -->
    <!-- ko text: person.LastName --><!-- /ko -->
</h2>

为 FluentKnockoutHelpers 提供 .NET 类型,您可以使用 Intellisense 和 Razor / CSHTML 中的编译器以风格方式执行此操作

@{
  var person = this.KnockoutHelperForType<Person>("person", true);
}

<div class="control-group">
    @person.LabelFor(x => x.FirstName).Class("control-label")
    <div class="controls">
        @person.BoundTextBoxFor(x => x.FirstName)
    </div>
</div>
<div class="control-group">
    @person.LabelFor(x => x.LastName).Class("control-label")
    <div class="controls">
        @person.BoundTextBoxFor(x => x.LastName)
    </div>
</div>
<h2>
    Hello,
    @person.BoundTextFor(x => x.FirstName)
    @person.BoundTextFor(x => x.LastName)
</h2>

查看SourceLive Demo以详细了解 FluentKnockoutHelper 在不平凡的 Durandal.js 应用程序中的功能。

于 2013-05-17T05:53:43.093 回答
7

是的,您绝对可以将 cshtml 文件与 Durandal 一起使用,并在服务器上利用 Razor。我认为这也意味着您需要 MVC,因此您也可以这样做并使用它的路由。

如果您不想要路由,那么您可以在 web.config 中设置 pages.Enabled,正如其他评论所建议的那样。

<add key="webpages:Enabled" value="true" /> 
于 2013-02-24T18:46:00.107 回答
5

我不建议您直接使用 .cshtml 文件作为视图。最好将 .cshtml 文件放在控制器后面。

例如,以 HotTowel 示例为例,编辑 /App/main.js,并将函数定义替换为以下内容:

define(['durandal/app', 
        'durandal/viewLocator', 
        'durandal/system',
        'durandal/plugins/router',
        'durandal/viewEngine', 
        'services/logger'],
function (app, viewLocator, system, router, viewEngine, logger) {

请注意,我们添加了对 Durandal viewEngine 的引用。然后我们需要更换

viewLocator.useConvention();

viewLocator.useConvention('viewmodels', '../../dynamic'); 
viewEngine.viewExtension = '/';

viewLocation.useConvention 的第一个参数将 /Apps/viewmodels/ 目录设置为视图模型 js 文件的位置,但对于视图位置,使用 URL http://example.com/dynamic/,扩展名为 ' /'。因此,如果 Durandal 正在寻找名为“shell”的视图,它将引用http://example.com/dynamic/shell/(这是因为视图目录是相对于 viewmodels 目录映射的,因此 /App/viewmodels/ ../../dynamic 会给你简单的 /dynamic)。

按照惯例,这个先前的 URL ( http://example.com/dynamic/shell/ ) 将被映射到控制器 DynamicController 和动作“Shell”。

在此之后,您只需添加一个控制器 - DynamicController.cs,如下所示:

// will render dynamic views for Durandal
public class DynamicController : Controller
{
    public ActionResult Shell()
    {
        return View();
    }

    public ActionResult Home()
    {
        return View();
    }

    public ActionResult Nav()
    {
        return View();
    }

    public ActionResult Details()
    {
        return View();
    }

    public ActionResult Sessions()
    {
        return View();
    }

    public ActionResult Footer()
    {
        return View();
    }
}

为上述每个操作创建 .cshtml 文件。通过这种方式,您可以使用控制器、服务器端 IoC 等为您的 SPA 生成动态视图。

于 2013-03-21T04:12:19.257 回答
2

DurandaljS 是一个客户端框架,主要为单页应用程序 (SPA) 奠定了坚实的基础。我假设您使用 asp.net Web API 作为您的服务器技术。在这种情况下,您可以在 API 控制器中确定用户的角色,并根据该返回数据给客户端。在客户端上,您可以使用 Knockout "if" 绑定来显示/隐藏页面的某些区域。

您可能可以做的是将此代码放在 Index.cshtml 中。

于 2013-02-24T15:44:57.860 回答
2

以下链接显示了如何自定义 moduleid 到 viewid 映射

http://durandaljs.com/documentation/View-Location/

按照惯例,durandal 尝试在以下步骤中查找查看 url

1)检查对象是否具有getView()返回dom或字符串的函数(视图的url)

2) 如果对象没有 getView 函数,则检查对象是否具有viewUrl属性

3) 如果上述两个步骤未能生成 url 或 DOM 视图 drundal 符合默认约定

使用 main.js 中定义的视图 url(视图文件夹的路径)将 moduleid 映射xyz.js到视图xyz.html

所以对于 moduleid xyz.js 视图的路径将是 views/xyz.html

您可以通过覆盖convertModuleIdToViewId函数来覆盖此默认映射行为。

因此,您可以通过多种方式为特定模型(.js 对象)自定义视图 url

于 2013-08-27T21:32:33.650 回答
1

我对 Durandal 做了一个扩展,它使您能够将 applicationContent div 与 applicationHost div 一起放置在您的 cshtml 文件中。在 applicationContent 中,您现在可以同时使用 ASP .Net MVC 语法和敲除绑定。

我唯一做的就是在 viewLocator.js 文件中添加一些额外的代码来查找 applicationContent div:

        locateViewForObject: function(obj, area, elementsToSearch) {
        var view;

        if (obj.getView) {
            view = obj.getView();
            if (view) {
                return this.locateView(view, area, elementsToSearch);
            }
        }

        if (obj.viewUrl) {
            return this.locateView(obj.viewUrl, area, elementsToSearch);
        }

        view = document.getElementById('applicationContent');
        if (view) {
            return this.locateView(view, area, elementsToSearch);
        }

        var id = system.getModuleId(obj);
        if (id) {
            return this.locateView(this.convertModuleIdToViewId(id), area, elementsToSearch);
        }

        return this.locateView(this.determineFallbackViewId(obj), area, elementsToSearch);
    },

您的原始 cshtml 文件现在可以执行以下操作:

<div class="row underheader" id="applicationContent">
<div class="small-5 columns">
    <div class="contentbox">
        @using (Html.BeginForm("Generate", "Barcode", FormMethod.Post, Attributes.Create()
                                                                                    .With("data-bind", "submit: generateBarcodes")))
        {
            <div class="row formrow">
                <label for="aantalBijlagen">@Translations.Label_AantalBijlagen</label>
            </div>
            <div class="row">
                <select name="aantalBijlagen" class="small-6 columns">
                    <option>0</option>
                    <option>1</option>
                    <option>2</option>
                    <option>3</option>
                    <option>4</option>
                </select>
            </div>
            <div class="row">
                <button class="button right" type="submit" id="loginbutton"><span class="glyphicon glyphicon-cog"></span> @Translations.Action_Generate</button>
            </div>
        }
    </div>
</div>
<div class="small-7 columns" data-bind="if: hasPdfUrl">
    <div class="contentbox lastcontent">
        <iframe data-bind="attr: {src: pdf_url}"></iframe>
    </div>
</div>

你可以在这里找到我的 durandal 项目的分支和一篇关于我在这里做了什么和如何做的小博文。

于 2014-02-09T10:01:40.707 回答
0

我对 DurandalJS 不是很熟悉,但因为它是一个客户端系统,所以在服务器上使用什么技术来生成 HTML 标记应该没有区别。因此,如果您使用 Razor CSHTML 文件在服务器上生成 HTML,DurandalJS 应该可以正常工作。

如果您遇到特定错误,请分享该错误,但我想不出它不起作用的任何原因。

于 2013-02-20T18:29:13.460 回答