如何实现以模型属性为条件的视图部分?

时间:2012-12-14 16:59:09

标签: asp.net-mvc asp.net-mvc-4 knockout.js client-side dynamic-html

我有这样的功能要求:

  
      
  • “公民身份”由3个单选按钮组成,即“南非公民”,“非南非人,有工作许可”和“非公民”   南非,没有工作许可“。
  •   
  • “工作许可证号码”是一个自由文本字段,限制为15个字符,如果出现“非南非”字样,则会激活   工作许可“在”公民“领域选择
  •   

我想为字段编辑器创建某种通用容器,例如“工作许可号码”,根据其他模型属性启用或禁用其包含的编辑器,例如本例中的“Citizenship”。这很容易实现首次检索和渲染视图模型时。

然而,当用户例如事情变得复杂时改变了“公民身份”的价值。只有UI字段已更改,并且没有模型属性,但决定是否启用“工作许可编号”的容器依赖于模型属性。

我只看到两个解决方案:

  1. 使用客户端(可能是JavaScript)视图模型,从服务器端视图模型构建,可能是Knockout.js场景。然后绕过正常表单提交并立即提交整个客户端模型。

  2. 当用户更改“Citizenship”值时,使用ajax调用更新服务器端模型,并更新依赖于“Citizenship”值的所有视图部件。这使事情复杂化,因为我必须有一个'工作'和'已提交'模型服务器端。保持较小变化的工作模型,例如“Citizenship”,然后当用户单击“保存”时,将所有更改移至“已提交”模型并保留到数据存储。

  3. 对于那些理解我的意思的人,我可以用什么其他方法来实现这一目标,或者我如何改进上面概述的技术?

1 个答案:

答案 0 :(得分:0)

我认为这种情况非常适合使用淘汰赛的客户端解决方案,正如您在第一个提出的解决方案中提到的那样。 Knockout使得以声明方式进行这种客户端UI操作变得非常容易。用户完成表单后,只需将客户端视图模型对象序列化为JSON并将其发布到服务层。

您提出的第二个解决方案不那么引人注目。其中的缺点是:

  1. 它需要服务器回发才能更新UI,这是一种不太理想的用户体验
  2. 您的服务器域模型现在必须具有工作和提交的模型,这会增加复杂性
  3. 使用MVVM模式实现这一点的代码和使用MVVM模式的客户端javascript视图模型非常简单:

    <div data-bind = "text: name"></div>
    <input type="radio" name="citizenship" value="yes" data-bind="checked: citizenship">South African Citizen<br/>
    <input type="radio" name="citizenship" value="nowithoutworkpermit" data-bind="checked: citizenship">Non South African, no work permit<br />
    <input type="radio" name="citizenship" value="nowithworkpermit" data-bind="checked:     citizenship">Non South African, with work permit<br />
    <div id="workpermit" data-bind="visible: citizenship() === 'nowithworkpermit'">
        <input type="text" name="workpermitinumber" />Work Permit number
    </div>
    
    <script src="/Scripts/knockout-2.2.0.js" ></script>
    <script>
        var MyApp = MyApp || {};
        MyApp.ViewModel = {
            citizenship: ko.observable(""),
            name: ko.observable("John")
        };
        ko.applyBindings(MyApp.ViewModel);
    </script>
    

    在这个例子中,我在MyApp.ViewModel中创建了一个视图模型。该模型有两个属性:名称和公民身份。我将“公民身份”属性数据绑定到无线电广告的“已检查”属性,以及显示工作许可证编号文本框的“可见”属性。

    当用户检查单选按钮时,knockout将更新视图模型的“citizenship”属性。视图模型属性中的此更改将依次通过knockout“visibile”绑定更新workpermit div的visibility css属性。当用户准备好提交表单时,您只需将MyApp.ViewModel序列化为JSON并通过网络发送。

    淘汰赛的文件非常出色(see here),我认为这将非常适合你想要完成的任务。