我在 VS2012 上获得了 DurandalJS StarterKit 模板......一切都很好......
但在某些观点中,我需要做这样的事情:
@if (Roles.IsUserInRole("Administrators"))
{
<p>Test</p>
}
但是,对于 durandal,我所有的视图都是“.html”文件......是否可以使用“.cshtml”文件来访问类似的信息?
或者有没有其他方法可以用 durandal 做到这一点?
初级
我在 VS2012 上获得了 DurandalJS StarterKit 模板......一切都很好......
但在某些观点中,我需要做这样的事情:
@if (Roles.IsUserInRole("Administrators"))
{
<p>Test</p>
}
但是,对于 durandal,我所有的视图都是“.html”文件......是否可以使用“.cshtml”文件来访问类似的信息?
或者有没有其他方法可以用 durandal 做到这一点?
初级
我这样做是这样的:
为 Durandal 视图创建一个通用控制器:
public class DurandalViewController : Controller
{
//
// GET: /App/views/{viewName}.html
[HttpGet]
public ActionResult Get(string viewName)
{
return View("~/App/views/" + viewName + ".cshtml");
}
}
注册路线:
routes.MapRoute(
name: "Durandal App Views",
url: "App/views/{viewName}.html",
defaults: new { controller = "DurandalView", action = "Get" }
);
将 Views/web.config 复制到 /App/views/web.config(以便 Razor 视图在此位置工作)。
这让我可以使用正常的 Durandal 约定(甚至是视图的 html 扩展名),并将 durandal 视图作为 cshtml 文件放在其正常位置,而无需添加任何更多的服务器代码。
如果您还有静态 html 视图,您也可以将 cshtml 视图放在子文件夹中或使用普通的 MVC /Views 文件夹。
我不建议将 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 的原因!)
特征:
没有 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>
查看Source或Live Demo以详细了解 FluentKnockoutHelper 在不平凡的 Durandal.js 应用程序中的功能。
是的,您绝对可以将 cshtml 文件与 Durandal 一起使用,并在服务器上利用 Razor。我认为这也意味着您需要 MVC,因此您也可以这样做并使用它的路由。
如果您不想要路由,那么您可以在 web.config 中设置 pages.Enabled,正如其他评论所建议的那样。
<add key="webpages:Enabled" value="true" />
我不建议您直接使用 .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 生成动态视图。
DurandaljS 是一个客户端框架,主要为单页应用程序 (SPA) 奠定了坚实的基础。我假设您使用 asp.net Web API 作为您的服务器技术。在这种情况下,您可以在 API 控制器中确定用户的角色,并根据该返回数据给客户端。在客户端上,您可以使用 Knockout "if" 绑定来显示/隐藏页面的某些区域。
您可能可以做的是将此代码放在 Index.cshtml 中。
以下链接显示了如何自定义 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
我对 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>
我对 DurandalJS 不是很熟悉,但因为它是一个客户端系统,所以在服务器上使用什么技术来生成 HTML 标记应该没有区别。因此,如果您使用 Razor CSHTML 文件在服务器上生成 HTML,DurandalJS 应该可以正常工作。
如果您遇到特定错误,请分享该错误,但我想不出它不起作用的任何原因。