9

我开始一个新项目,并且热衷于使用KnockoutJS + Web API,这些对我来说是新的,我对Web Api有很好的理解,但是现在Knockout很难让我头脑发热。ASP.Net Web Api + KnockoutJs + MVC4 - 将它们结合在一起

这是我的我多么希望我的应用程序工作的初步想法:

  • 我有一个标准的MVC控制器,如LeadsController
  • LeadsController有一个名为ListLeadsAction,这实际上并不返回任何数据,但只是返回一个模板来显示来自Knockout的数据。
  • ListLeads视图通过AJAX调用我的API控制器LeadsApiController获得的潜在客户清单显示
  • 引线的数据被映射到KnockoutJs视图模​​型(我不想从服务器端复制我的视图模型转换为JavaScript查看模型)
  • 我想尽可能多地使用外部JavaScript文件,而不是使我的HTML页面充满JavaScript。

我见过很多例子,但其中大多数都会在首页加载时返回一些初始数据,而不是通过ajax调用。

所以我的问题是,如何创建我的JavaScript viewModel从ajax检索,其中ajax url是使用Url.Content()创建的。

另外,如果我需要此ViewModel上的附加计算值,如何从服务器端扩展映射视图模型?

如果我没有很好地解释我自己,请让我知道你不知道什么,我会尝试更新我的问题,以便更明确。

回答

4

我认为你的设计是一个好主意。事实上,我正在开发一个应用程序,现在就使用这个设计!

您不必在页面中嵌入初始数据。取而代之的是,当你的页面加载,创建一个空的视图模型,称之为ko.applyBindings,然后启动一个AJAX调用,当它完成,这将填充视图模型:

$(function() { 
    var viewModel = { 
     leads: ko.observableArray([]) // empty array for now 
    }; 

    ko.applyBindings(viewModel); 

    $.getJSON("/api/Leads", function (data) { 
     var newLeads = ko.mapping.fromJS(data)(); // convert to view model objects 
     viewModel.leads(newLeads); // replace the empty array with a populated one 
    }); 
}); 

你要放一个“加载”消息的地方直到AJAX呼叫完成。

,生成 “/ API /信息” URL,使用Url.RouteUrl:(这是假设在Global.asax中或App_Start \ RouteConfig.cs程序被命名为 “DefaultApi” 你的API路线)

<script> 
    var apiUrl = '@Url.RouteUrl("DefaultApi", new { httproute = "", controller = "Leads" })'; 
</script> 

上面使用了挖空映射插件将AJAX JSON结果转换为挖空视图模型。默认情况下,生成的视图模型将为JSON中的每个属性都有一个可观察的属性。要定制这个,例如添加额外的计算属性,请使用挖空映射插件的"create" callback

在我的应用程序中得到了这一点之后,我发现我想从服务器端视图模型获取更多的元数据给客户端代码,例如需要哪些属性以及每个属性的验证。在敲击映射“创建”回调中,我想要这些信息以便在视图模型中自动生成附加属性和计算可观察值。所以,在服务器端,我使用了一些MVC框架类和反射来检查视图模型,并将一些元数据生成为嵌入到相关视图中的JavaScript。在客户端,我有外部JavaScript文件,它们连接了挖空映射回调并根据页面中提供的元数据生成视图模型。我的建议是首先在每个视图中手工编写基本视图模型定制和其他JavaScript,然后在重构时将通用JavaScript函数移出到外部文件中。每个视图最终只能使用特定于该视图的最小JavaScript,此时您可以考虑编写一些C#以从服务器端视图模型注释生成该JavaScript。

+0

嗨乔。你的方法是绝对正确的,我一直在寻找的很多教程/博客都有类似的解决方案。我一直在评估这种方法,我们开始的大型Web应用程序。我的问题是写很多的JS,我觉得很难管理。还有什么是使用MVC和WebAPI控制器,为什么使用MVC控制器传递空视图?看起来像它的创造性的双重性。 – Yashvit 2013-07-26 04:11:57

+0

MCV返回页面的静态HTML。 Web API返回页面的视图模型JSON数据。如果您不喜欢“空”视图但仍想使用Knockout,则可以将视图模型数据序列化为服务器上的JSON并将其注入到HTML视图中,只要您不想使用AJAX并不介意HTML不再可缓存。 – 2013-07-26 12:38:18

+0

现在有很多解决大型JS应用程序的解决方案。在我写这个答案的那一年,我们现在有Breeze.js和Durandal来组织一切,并实施管道。查看Breeze的TempHire演示项目。 – 2013-07-26 12:41:47

1

为URL问题在一个地方添加这个在您的_Layout.cshtml它是使用它的文件之前:

<script> 
    window._appRootUrl = '@Url.Content("~/")'; 
</script> 

然后你可以使用window._appRootUrl组成与字符串连接或网址像URI.js这样的JavaScript库的帮助。

至于额外的计算值,你可能想要使用一个挖空计算observable。如果这是不可能的,或者您更愿意在.Net中执行此操作,则只能使用getter创建属性,但如果依赖于它们更新客户端上的其他属性,则不会更新。

+0

谢谢你的回答,今天下午将对此进行调查。我指的是使用淘汰赛计算可观察...只是想知道我是如何转换由淘汰赛映射插件创建的ViewModel添加新的计算值到它...我扩展它以某种方式吗?谢谢。 – 2012-08-17 10:42:50