【问题标题】:Knockout in Dialog to ASP MVC issues在对话框中敲除 ASP MVC 问题
【发布时间】:2015-12-05 13:20:59
【问题描述】:

我是 KnockoutJS 的新手,在理解使用 Knockout 数据绑定的最佳方法时遇到了一些问题。 Fiddle

我当前的项目使用一个对话框弹出窗口来填充诸如值表之类的内容。但目前,我只通过将值推送到 Knockout observableArray 来将值从对话框复制到表中。必须有一种方法可以进一步简化这个过程(我至少还有 8 个以上这些类型的对话框,有些有 15 个以上的字段!)

<h4>Affiliations</h4>
<table id="AffiliationsTable" data-bind="foreach: affiliations">
    <thead>
        <tr>
            <td>Organization Name</td>
            <td>Affiliation Role</td>
        </tr>
    </thead>
    <tr>
        <td>
            <input data-bind="value: OrganizationName, attr: {name: 'Affiliations[' + $index() + '].OrganizationName'}">
        </td>
        <td>
            <input data-bind="value: AffiliationRole, attr: {name: 'Affiliations[' + $index() + '].AffiliationRole'}">
        </td>
    </tr>
</table>
<div id="dialogAffiliation" data-bind="dialog: {autoOpen: false, title: 'Affiliation' }, dialogVisible: isOpen">
    <label for="OrganizationName">Organization Name</label>
    <input type="text" name="OrganizationName" value="" class="text ui-widget-content ui-corner-all" id="OrganizationNameInsert">
    <label for="AffiliationRole">Affiliation Role</label>
    <input type="text" name="AffiliationRole" value="" class="text ui-widget-content ui-corner-all" id="AffiliationRoleInsert"><br />
    <button data-bind="click: addAffiliation">Save</button>
</div>

<div>
    <button data-bind="click: open">Add Affiliations</button>
</div>

希望 KO 代码可以做出最大的改变,但我似乎想不出改进的地方。也许用一个可观察的填充对话框,该可观察对象在保存单击时移动到表 DOM。或者比这更聪明的东西。任何建议将不胜感激!

var viewModel = function() {
    var self = this;
    self.isOpen = ko.observable(false);
    self.open = function () {
        this.isOpen(true);
    };
    self.close = function () {
        this.isOpen(false);
    };
    self.affiliations = ko.observableArray([
            { OrganizationName: ko.observable('name'), AffiliationRole: ko.observable("role")}, { OrganizationName: ko.observable('name2'), AffiliationRole: ko.observable("role2") }
    ]);

    self.addAffiliation = function () {
        self.affiliations.push({ OrganizationName: document.getElementById("OrganizationNameInsert").value, AffiliationRole: document.getElementById("AffiliationRoleInsert").value });
        $("#dialogAffiliation").dialog('close');
    };
};

ko.applyBindings(new viewModel());

http://jsfiddle.net/timotheusg/8c8xhf55/

【问题讨论】:

  • 不是您要求的解决方案,但为什么不简单地将空白字段添加到屏幕上呢?您可以完全绕过打开模式,并且这些字段仍然可以编辑。更少的点击,更好的用户界面 (imo)。
  • A.老板想要这样。 B. 某些字段将仅转换为文本(在单击之前不可编辑)。
  • 好吧...如果必须,您可以创建一个代表您的表单/对象的模型。然后,使用 KOMapping 插件,您可以将数据映射到该对象的新实例并将其添加到您的集合中。
  • 我添加了一个答案。我所在的团队使用 KO 将模型从客户端传递到服务器(反之亦然)。它可能需要一些尝试,但是能够传递数据的 JSON 表示形式,然后将它们转换为 observables、js 对象或服务器模型,背后有相当大的力量。

标签: javascript jquery asp.net asp.net-mvc knockout.js


【解决方案1】:

一般来说,我建议使用模型。它允许一致性,并增加了能够使用 Knockout 的映射插件来传递和映射数据的好处。

var viewModel = {
    listOfObjects: ko.observableArray(),
    object: {
        affiliation: ko.observable(),
        name: ko.observable(),
        title: ko.observable()

}

有一个绑定到“对象”的表单,保存按钮会调用类似的函数:

// Turn object into plain JS object (there is also a toJSON)
var formData = ko.mapping.toJS(viewmodel.object);
// Push into array
listOfObjects.push(ko.mapping.fromJS(formData, mapping));

参考:http://knockoutjs.com/documentation/plugins-mapping.html

值得注意的是,您需要下载并包含映射插件的源代码才能使用此功能。我相信它是由 KO 的首席开发人员创建的。

【讨论】:

    【解决方案2】:

    您可以(并且应该)避免使用 jQuery 在 bindingHandler 之外处理 DOM。在您的视图模型中有一个对象,对话框输入绑定到其可观察对象。然后,当您将该对象推送到列表中时,您可以创建一个新的、干净的输入对象。

    var viewModel = function () {
        var self = this;
        self.isOpen = ko.observable(false);
        self.open = function () {
            this.isOpen(true);
        };
        self.close = function () {
            this.isOpen(false);
        };
    
        function newAffiliation(name, role) {
            return {
                OrganizationName: ko.observable(name),
                AffiliationRole: ko.observable(role)
            };
        }
    
        self.affiliations = ko.observableArray([
        newAffiliation('name1', 'role1'),
        newAffiliation('name2', 'role2')]);
    
        self.dialogAffiliation = ko.observable(newAffiliation());
    
        self.addAffiliation = function () {
            self.affiliations.push(self.dialogAffiliation());
            self.dialogAffiliation(newAffiliation());
            self.close();
        };
    };
    

    您可以通过让小部件订阅您的isOpen 元素来消除绑定处理程序的update 部分。

    ko.bindingHandlers.dialog = {
        init: function (element, valueAccessor, allBindingsAccessor) {
    
            /* .... stuff you wrote .... */   
            allBindingsAccessor().dialogVisible.subscribe(function (newValue) {
                $el.dialog(newValue ? 'open' : 'close');
            });
    
            /* ... more stuff you wrote ...*/
    
        }
    };
    

    我更新了你的Fiddle。我摆脱了 id 属性,因为您不需要搜索它们。我去掉了名称属性,因为它们在代码中很杂乱,但你可能有理由想要它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-15
      • 1970-01-01
      • 2015-06-04
      • 2010-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多