【问题标题】:Knockout and ASP.NET MVC multi page淘汰赛和 ASP.NET MVC 多页
【发布时间】:2015-03-01 14:03:20
【问题描述】:

我对淘汰赛还很陌生,在应用我的绑定和多个视图时,我不知道如何使用 ASP.NET MVC 最好地构建淘汰赛。我了解您如何在单页应用程序中做到这一点。但我的应用程序由多个服务器端控制器和多个视图组成。每个视图都可以有自己的淘汰视图模型。

我应该何时以及如何应用绑定?我最后加载了我所有的 javascript,这意味着我不能内联调用我的视图模型。

使用某种 MasterViewModel 然后在我的视图中使用 with 绑定是一种好习惯吗(这是我能想到的唯一解决方案)?

【问题讨论】:

    标签: javascript c# asp.net asp.net-mvc knockout.js


    【解决方案1】:

    是的,这是一个很好的做法,因为如果您尝试为多个视图制作单个视图模型,那么一切看起来都很复杂,并且会失去可读性(完全取决于复杂程度)。

    你必须尝试这样的事情才能使事情变得可读和简单

    查看模型:

    var MasterViewModel = {
        vm1 : new ViewModel1(),
        vm2 : new ViewModel2(),
        vm3 : new ViewModel3(),
        vm4 : new ViewModel4(),
    }
    
    ko.applyBindings(MasterViewModel);
    

    另一种可行的方法,只需向ko.applybindings 添加附加参数即可区分哪个视图属于哪个视图模型

    示例:

    //view
    <div id='viewmodel1'>
    </div>
    <div id='viewmodel2'>
    </div>
    
    var vm1 = function(){ //code}
    var vm2 = function(){ //code}
    
    ko.applyBindings(new vm1(), document.getElementById("viewmodel1"));
    ko.applyBindings(new vm2(), document.getElementById("viewmodel2"));
    

    如果我记得足够清楚,stack-overflow 中几乎没有类似的帖子,您可以参考

    【讨论】:

    • 这在具有不同部分的单页应用程序中效果很好。但是我应该何时以及如何应用绑定?我不能内联,因为我在 BODY 的末尾加载了所有的 javascript。您可以这样绑定,但您必须在绑定之前对 document.getElementById 进行 nullcheck 才能知道该元素是否存在于页面上。
    【解决方案2】:

    为每个 ASP.NET 视图创建一个绑定到 mvc 视图的 ViewModel。我会在 ASP.NET MVC 模型之后命名 ViewModel。

    ASP.NET MVC 模型:

    public class LoginViewModel
    {
        [Required]
        [Display(Name = "Email")]
        [EmailAddress]
        public string Email { get; set; }
    
        [Required]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        public string Password { get; set; }
    
        [Display(Name = "Remember me?")]
        public bool RememberMe { get; set; }
    }
    

    淘汰视图模型:

    var LoginViewModel = function () {
        var self = this;
    
        self.email = ko.observable();
        self.password = ko.observable();
        self.rememberMe = ko.observable();
    
        self.login = function () {
            ...
        }
    };
    

    我通常使用 ASP.NET 捆绑捆绑所有视图模型 .js,然后在每个 MVC 视图中绑定 Knockout 视图模型。

    $(function() {
        ko.applyBindings(new LoginViewModel());
    });
    

    如果您需要在第一次加载时从 mvc 模型填充模型,我会使用 json.net 序列化为 json,然后将其传递给 ViewModel 承包商:

    var loginModel = '@JsonConvert.SerializeObject(Model)';
    
    $(function() {
        ko.applyBindings(new LoginViewModel(loginModel));
    });
    

    然后在您的淘汰视图模型中,您可以从传递给承包商的模型中填充 observables:

    var LoginViewModel = function (loginModel) {
        var self = this;
    
        self.email = ko.observable(loginModel.email);
        self.password = ko.observable(loginModel.password);
        self.rememberMe = ko.observable(loginModel.rememberMe);
    

    为了对 json 使用驼峰式大小写,我将 json.net 更改为序列化为 camlecase。

    如果您有一个类似于 SPA 的复杂页面(例如具有多个步骤的表单页面,本质上是具有多个视图状态的页面),您将使用一些 MasterViewModel,正如 supercool 所解释的那样。

    【讨论】:

    • 我无法在每个 MVC 视图中绑定,因为我在 BODY 的末尾加载了所有 javascript。否则我会完全按照你的建议去做。
    • 当然可以。在身体底部使用 @RenderSection("scripts", required: false) 。然后在您的视图中,您可以使用@section scripts { .. } 并且脚本将呈现在正文的底部
    • 不知道@RenderSection。有时您会错过什么,这让我感到惊讶!谢谢
    猜你喜欢
    • 2015-03-12
    • 2014-04-13
    • 2016-11-03
    • 2013-06-15
    • 2016-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-17
    相关资源
    最近更新 更多