jquery - 大型 MVC Web 应用程序 - 使用 Knockout 和 Razor

标签 jquery asp.net-mvc architecture knockout.js knockout-mapping-plugin

我正在开发一个大型 Web 应用程序,但在使用 knockout 和 MVC 正确构建它时遇到问题。

我目前有一个基本 View 模型,我将其传递到所有 View 中,其中包含有关当前登录用户的基本数据

//Example Code
public class BaseViewModel {
    public String FullName;
    public String Email;

    //A bunch of other similar values
}

然后,我拥有特定于网站上每个页面(即配置文件)的 View 模型,这些模型继承了 BaseViewModel 类

//profile.cshtml
public class UserProfileViewModel : BaseViewModel {
    public String Address;
    public String PhoneNumber;

    //Other similar values
}

//entity.cshtml
public class UserEntityViewModel : BaseViewModel {
    public String EntityValue;
    public Int32 EntityNumber;

    //Other similar values
}

我已经使用 knockout 可观察值在 JavaScript 中重新定义了整个数据模型,以便我可以创建 MVC 模型中拥有的任何类型的对象。然后,我在 javascript 中定义了几个 View 模型,它们与我的 MVC View 模型基本相同,以允许加载、创建、编辑、删除功能。

我发现这在我想从个人资料页面创建新实体的情况下非常有效。我可以创建 View 模型的新实例并将其绑定(bind)到新的 jquery 对话框,单击“确定”按钮后,我可以在 knockout View 模型中调用一个事件来保存或创建实体。

当我想要将数据加载到特定页面时(即我想使用我的 knockout 数据模型填充个人资料页面),这种架构效果不太好。我遇到了需要确定我所在的页面并将特定 View 模型绑定(bind)到该页面的问题。我真的不认为下面的代码很优雅。

$(function() {
    if ($('.tweak-list').length) {
        var id = $('.tweak-list').attr('data-songid');
        var vm = new my.tweaksviewmodel({ songid: id });
        ko.applyBindings(vm);
    }
});

有人对我应该如何构建这个有任何建议吗?我认为最好在javascript中创建一个BaseViewModel并使用knockout映射插件http://knockoutjs.com/documentation/plugins-mapping.html自动创建我的各种数据模型。也就是说,它并没有真正解决确定模型从哪个页面绑定(bind)以便加载适当数据的问题。

编辑 1

此架构还有一个限制,即我无法利用模态弹出窗口来添加数据,因为我需要将 View 模型重新绑定(bind)到每个模态。

大家有什么想法吗?

最佳答案

我建议按照以下方式构建它:

为每个页面创建一个具有特定 KnockOut ViewModel 的不同 JavaScript 模块:

var app = app || {};
app.pages = app.pages || {};

app.pages.userProfile = (function () {

    function UserProfileViewModel() {
        //view model specific code
    };

    function init() {
        ko.applyBindings(new UserProfileViewModel());
    };

    return {
        init: init
    };
}());

指定在 Razor View 中应使用哪个 JS 模块:

@model dynamic

@{
    ViewBag.CurrentPageJsHandler = "app.pages.userProfile";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<p>Page specific content</p>

将页面特定模块初始化代码添加到布局文件:

<html>
<body>   
    <div id="content">
        @RenderBody()
    </div>      
    @if (@ViewBag.CurrentPageJsHandler != null)
    {
        <script>
            $(function() {
                app.currentPage = @ViewBag.CurrentPageJsHandler;
                app.currentPage.init();
            });
        </script>
    }    
</body>
</html>

这样你就可以将所有页面相关的代码封装在不同的模块中。由于每个 JS 模块都有唯一的名称,您可以将它们全部绑定(bind)在一起并包含在布局中。

关于jquery - 大型 MVC Web 应用程序 - 使用 Knockout 和 Razor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14763889/

相关文章:

javascript - 可以为 jquery.ajaxSetup() 设置范围吗?

javascript - 如何创建第二张图像而不是填充为单词

oop - 在哪里放置处理两个类之间关系的方法?

javascript - parent() 不适用于事件元素

c# - 回发后隐藏的表单字段未出现在 MVC 模型中

javascript - ASP Net MVC 从 JS 错误调用 Controller 中的函数

sql-server - 我应该如何使用 Redis 作为 SQL Server 的缓存?

java - 在运行时更改 Guice 绑定(bind)

architecture - 如何将我的推荐系统集成到我的网站中?

javascript - 我的推送菜单中的 body 动画不起作用