代码之家  ›  专栏  ›  技术社区  ›  Rei Miyasaka

ASP.NET MVC中的“内联”积垢

  •  2
  • Rei Miyasaka  · 技术社区  · 14 年前

    假设我有一个Companies表,它与Employees表有很多关系。

    我有一个添加/编辑公司页面,但我也希望能够找到/添加新的/现有的员工,而不必先为每个员工打开另一个CRUD页面。

    我将为每个员工输入一个英文名和一个日文名,所以博客软件用于编辑标签的常用技巧不会太好。

    它不需要太漂亮,因为它是供内部使用的。

    有什么切实可行的办法?我想我应该使用jQuery,但我几乎不知道如何使用它。

    我熟悉WPF/Silverlight,但是。。。你知道:)

    2 回复  |  直到 12 年前
        1
  •  8
  •   Nathan Taylor    14 年前

    最简单的方法是使用ASP.NETMVC对可枚举集合绑定模型的支持。基本上,当您为公司创建员工时,他们将被附加到使用特定字段命名结构的列表中,MVC的modelbinder可以使用该结构返回项目(员工)列表。

    public class Company
    {
        public string Name { get; set; }
        public IEnumerable<Employee> Employees { get; set; }
    }
    
    public class Employee
    {
        public string EnglishName { get; set; }
        public string JapaneseName { get; set; }
    }
    

    Company Name: <input type="text" name="Name" />
    
    <!-- Employee 1 -->
    English Name: <input type="text" name="Employees[0].EnglishName" />
    Japanese Name: <input type="text" name="Employees[0].JapaneseName" />
    
    <!-- Employee 2 -->
    English Name: <input type="text" name="Employees[1].EnglishName" /> 
    Japanese Name: <input type="text" name="Employees[1].JapaneseName" />
    
    <!-- Employee 2 -->
    English Name: <input type="text" name="Employees[2].EnglishName" /> 
    Japanese Name: <input type="text" name="Employees[2].JapaneseName" />
    

    在上面的示例中,您会注意到,对于每个employee字段,fieldname上都有一个序号索引器,它告诉ASP.NET MVC您正在绑定到一个列表,并且每个employee[n]都是要进行模型绑定的单个对象。保持这些索引的顺序很重要,因为如果缺少索引,列表将无法正确绑定。

    如果这一切都正确完成,那么您可以定义一个操作来处理接收公司对象作为参数的窗体。MVC将自动为您处理其余的事务。


    当然,上面的示例假设雇员的数量是静态的,这可能永远不会是这种情况,因此为了使它更灵活,我们可以使用jQuery在定义每个雇员时为他们创建新行。如前所述,索引的顺序很重要,必须保持一致。

    $('.add-employee').click(function() {
        var nextIndex = 0;
        var lastRow = $(this).siblings('.row:last');
        if (lastRow.length > 0) {
            var lastRegion = lastRow.find('input:last');
            if (lastRegion.length > 0 && /\[(\d+)\]/.test(lastRegion.attr('name')) !== null) {
                var key = lastRegion.parent().find('.key:text');
                if (key.val() === '') {
                    key.focus();
                    return;
                }
                nextIndex = parseInt(/\[(\d+)\]/.exec(lastRegion.attr('name'))[1], 10) + 1;
            }
        }
    
        var namePrefix = 'Employees[' + nextIndex + ']';
        var newItem = '<div class="row">\n'
                        + 'English Name: <input type="text" name="' + namePrefix + '.EnglishName" /><br />\n'
                        + 'Japanese Name: <input type="text" name="' + namePrefix + '.JapaneseName" />&nbsp;\n'
                        +  '<a href="#" class="remove-employee">Remove</a>\n'
                        + '</div>';
        $(this).before(newItem);
    });
    
    $('.remove-employee').live('click', function() {
        var parent = $(this).parent();
        parent.slideUp();
        parent.nextAll('div').children(':text').each(function(index, element) {
            element = $(element);
            if (/\[(\d+)\]/.test(element.attr('name')) !== null) {
                element.attr('name', element.attr('name').replace(/\[(\d+)\]/, '[' + (parseInt(/\[(\d+)\]/.exec(element.attr('name'))[1], 10) - 1) + ']'));
            }
        });
        parent.remove();
        return false;
    });
    

    要使用这些单击处理程序,必须定义一个类名为“add employee”的链接/按钮,然后在每个雇员记录(与该雇员的字段位于同一容器中)旁边定义一个名为“remove employee”的附加链接/按钮。注意,remove employee处理程序上使用了live()绑定,这将确保通过第一个函数添加的行具有有效的remove链接。

        2
  •  0
  •   nerraga    14 年前

    首先想到的是构建一个控制器来处理employee模型上的crud操作,但是不是返回viewresult,而是返回jsonresult或xmlresult(mvccontrib)。这有效地将您的控制器转变为一个web服务,允许您利用silverlight或jquery进行ui(比如jqueryui)和/或服务交互(jquery/ajax)。