无法在Knockoutjs中添加新用户

时间:2017-04-26 09:39:08

标签: jquery knockout.js bootstrap-modal

我正在使用knockoutjs使用foreach循环在表格中显示多条记录 Adduser按钮允许在用户输入新用户时使用我们软件的早期版本 单击Adduser,它会显示tr中的输入字段,以便添加用户。 现在我的任务是在模​​态弹出窗口中显示输入表单。但我的问题是数据绑定在表体标签和adduser按钮和模态弹出div是表bosy标签之外 所以它给出了错误,如

  

“错误:无法解析绑定。   消息:ReferenceError:未定义LoginName;   绑定值:value:LoginName,valueUpdate:'keyup'“

以下是代码

<table class="report-table cstm-report-tbl" data-bind="if: CompanyId()">
    <thead>
        <tr>
            <th>
                Login
            </th>
            <th>
                Email
            </th>
            <!-- ko if: $root.EditId() !== null -->
            <!-- /ko -->
        </tr>
    </thead>

    <tbody data-bind="foreach: Users">
        <tr>
            <!-- ko if: $root.EditId() === Id() -->
            <td><span data-bind="click: $root.Edit, text: LoginName, css: { clickable: $root.EditId() === null },  attr: {'data-target': '#myModal' + Id()}" data-toggle="modal"></span></td>
            <td>
                <span data-bind="text: EditEmail" />
            </td>

            <!-- /ko -->
            <!-- ko ifnot: $root.EditId() === Id() -->
            <td><span data-bind="click: $root.Edit, text: LoginName, css: { clickable: $root.EditId() === null },  attr: {'data-target': '#myModal' + Id()}" data-toggle="modal"></span></td>
            <td data-bind="text: Email"></td>
            <!-- ko if: $root.EditId() === 0 -->
            <!--<td></td>
            <td></td>
            <td></td>-->
            <!-- /ko -->
            <!-- /ko -->
        </tr>
        <tr class="modal fade cstm-resident-modal cstm-admin-popbox" data-bind="attr: { id: 'myModal' + Id()}" role="dialog" tabindex="-1">
            <td colspan="3" class="modal-dialog" role="document">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal">&times;</button>
                    <h4 class="modal-title">Client Admins</h4>
                </div>
                <div class="modal-content">
                    <div class="input-wrpr">
                        <div class="label">
                            <label>Login Name</label>
                        </div>

                        <div class="field">
                            <input data-bind="visible: Id() === 0, value: LoginName, valueUpdate: 'keyup'" type="text">
                            <span data-bind="visible: Id() !== 0, text: LoginName" style="display: none;"></span>
                        </div>
                    </div>
                    <div class="input-wrpr">
                        <div class="label">
                            <label>Email</label>
                        </div>
                        <div class="field">
                            <input data-bind="value: EditEmail, valueUpdate: 'keyup'" type="text">
                        </div>
                    </div>
                    <div class="input-wrpr">
                        <div class="label">
                            <label>Password</label>
                        </div>
                        <div class="field">
                            <input data-bind="value: Password, valueUpdate: 'keyup'" type="text">
                        </div>
                    </div>
                    <div class="input-wrpr">
                        <div class="label">
                            <label>Is Approved</label>
                        </div>
                        <div class="field">
                            <input data-bind="checked: IsApproved, visible: $root.EditId() !== 0" style="display: none;" type="checkbox">
                            <span data-bind="visible: $root.EditId() === 0">N/A</span>
                        </div>
                    </div>
                    <div>
                        <div id="InlineEditActionPanel">
                            <span class="" data-bind="click: $root.Save, css: { clickable: $root.IsValid }">Save</span>
                            <span class="clickable" data-bind="click: $root.CancelEdit" data-dismiss="modal">Cancel</span>
                        </div>
                    </div>
                </div>
            </td>
        </tr>
        <!--<tr>
            <td class="add-user-popbx" data-bind="attr: { colspan: $root.EditId() === null ? 4 : 5 }">
                <span class="add-usr-btn" data-bind="click: $root.Add, css: { clickable: $root.EditId() === null },  attr: {'data-target': '#myModal' + Id()}" data-toggle="modal">Add new user</span>
            </td>
        </tr>-->
    </tbody>
    <tfoot>

        <tr>
            <td class="add-user-popbx" data-bind="attr: { colspan: $root.EditId() === null ? 4 : 5 }">
                <span class="add-usr-btn" data-bind="click: $root.Add, css: { clickable: $root.EditId() === null }" data-toggle="modal" data-target="#myModal2">Add new user</span>
            </td>
        </tr>
        <tr class="modal fade cstm-resident-modal cstm-admin-popbox" id="myModal2" role="dialog" tabindex="-1">
            <td colspan="3" class="modal-dialog" role="document">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal">&times;</button>
                    <h4 class="modal-title">Client Admins</h4>
                </div>
                <div class="modal-content">
                    <div class="input-wrpr">
                        <div class="label">
                            <label>Login Name</label>
                        </div>

                        <div class="field">
                            <input data-bind="visible: Id() === 0, value: LoginName, valueUpdate: 'keyup'" type="text">
                            <span data-bind="visible: Id() !== 0, text: LoginName" style="display: none;"></span>
                        </div>
                    </div>
                    <div class="input-wrpr">
                        <div class="label">
                            <label>Email</label>
                        </div>
                        <div class="field">
                            <input data-bind="value: EditEmail, valueUpdate: 'keyup'" type="text">
                        </div>
                    </div>
                    <div class="input-wrpr">
                        <div class="label">
                            <label>Password</label>
                        </div>
                        <div class="field">
                            <input data-bind="value: Password, valueUpdate: 'keyup'" type="text">
                        </div>
                    </div>
                    <div class="input-wrpr">
                        <div class="label">
                            <label>Is Approved</label>
                        </div>
                        <div class="field">
                            <input data-bind="checked: IsApproved, visible: $root.EditId() !== 0" style="display: none;" type="checkbox">
                            <span data-bind="visible: $root.EditId() === 0">N/A</span>
                        </div>
                    </div>
                    <div>
                        <div id="InlineEditActionPanel">
                            <span class="clickable" data-bind="click: $root.Save, css: { clickable: $root.IsValid }">Save</span>
                            <span class="clickable" data-bind="click: $root.CancelEdit" data-dismiss="modal">Cancel</span>
                        </div>
                    </div>
                </div>
            </td>
        </tr>
    </tfoot>
</table>

跟随js代码

ResPortal.Admin.MaAdmin = function () {
var maAdminViewModel = function () {
    var that = this;

    this.Busy = ko.observable(false);

    this.Companies = ko.observableArray();

    this.CompanyId = ko.observable(0);

    this.CompanyName = ko.computed(function () {
        var i;

        if (that.Busy()) {
            return "";
        }

        for (i = 0; i < that.Companies().length; i++) {
            if (that.Companies()[i].Id == that.CompanyId()) {
                return that.Companies()[i].Name;
            }
        }
    });

    this.EditId = ko.observable();

    this.Users = ko.observableArray();

    this.Add = function () {
        var newUser;

        if (that.EditId() !== null) {
            return;
        }

        newUser = {
            EditEmail: ko.observable(""),
            Email: ko.observable(""),
            Id: ko.observable(0),
            IsApproved: ko.observable(true),
            LoginName: ko.observable(""),
            Password: ko.observable("")
        };

        that.Users.push(newUser)
        that.EditId(0);
    };

    this.Edit = function (user) {
        if (that.EditId() !== null || that.EditId() === user.Id()) {
            return;
        }

        that.EditId(user.Id());
    };

    this.Save = function (user) {
        $.ajax({
            type: "POST",
            url: "Default.aspx/SaveAdmin",
            data: JSON.stringify({
                companyId: that.CompanyId(),
                userId: user.Id(),
                login: user.LoginName(),
                email: user.EditEmail(),
                newPassword: user.Password(),
                isActive: user.IsApproved()
            }),
            contentType: "application/json; charset=utf-8",
            dataType: "json"
        }).fail(function (data) {
            ResPortal.Helpers.notify(data.d.Message || "Server error", "error");
        }).success(function (data) {
            if (data.d.Success) {
                ResPortal.Helpers.notify(data.d.Message || "User updated", "success");

                user
                    .Email(user.EditEmail())
                    .Password("");

                if (user.Id() === 0) {
                    user.Id(data.d.Data);
                } else {
                    if (!user.IsApproved()) {
                        that.Users.remove(user);
                    }
                }

                that.CancelEdit();
            } else {
                ResPortal.Helpers.notify(data.d.Message || "Server error", "error");
            }
        });
    };

    this.CancelEdit = function () {
        var user = _.find(that.Users(), function (u) {
            return u.Id() === that.EditId();
        });

        if (user) {
            user.EditEmail(user.Email());

            if (user.Id() === 0) {
                that.Users.remove(user);
            }
        }

        that.EditId(null);
    };

    this.CompanyId.subscribe(function (value) {
        if (!value) {
            return null;
        }

        that.Busy(true);

        that.EditId(null);

        $.ajax({
            type: "POST",
            url: "Default.aspx/GetClientAdmins",
            data: JSON.stringify({ companyId: that.CompanyId() }),
            contentType: "application/json; charset=utf-8",
            dataType: "json"
        }).fail(function (data) {
            ResPortal.Helpers.notify(data.d.Message || "Server error", "error");
        }).done(function (data) {
            var users = data.d.Data.Users;

            // Attach additional properties for editing
            _.each(users, function (user) {
                user.EditEmail = ko.observable(user.Email);
                user.Email = ko.observable(user.Email);
                user.Id = ko.observable(user.Id);
                user.IsApproved = ko.observable(user.IsApproved);
                user.LoginName = ko.observable(user.LoginName);
                user.Password = ko.observable("");
            });

            that.Users(users);

            that.Busy(false);
        });
    });

    this.IsValid = ko.computed(function () {
        var user,
            create;

        user = _.find(that.Users(), function (u) {
            return u.Id() === that.EditId();
        });

        if (!user) {
            return false;
        }

        create = user.Id() === 0;

        if (create) {
            return user.LoginName().length && user.EditEmail().length && user.Password().length;
        } else {
            return user.EditEmail().length;
        }
    });
},
    vm = new maAdminViewModel();

ko.applyBindings(vm, document.getElementById("AdminPanel"));

vm.Busy(true);

$.get("../Services/CompanyService.svc/GetCompanies", function (data) {
    _.each(data, function (co) {
        vm.Companies.push(co);
    });
}).fail(function (d) {
    ResPortal.Helpers.notify(["Server error", "(Click this message to close)"], "error", true);
}).always(function () {
    vm.Busy(false);
});

// Polyfills

};

请帮帮我

1 个答案:

答案 0 :(得分:0)

您已通过tbody将用户绑定到foreach中的每一行。但是,对于绑定到tfoot的{​​{1}}内的用户字段,您也具有相同的绑定,而不是任何用户。 vm没有vmLoginName等属性。

我不确定您将如何使用Id

如果要将其用作编辑用户区域,可以将当前编辑用户添加到模型中:

tfoot

并绑定到this.EditUser = ko.pureComputed(function() { if (that.EditId() == null) { return null; } var user = _.find(that.Users(), function(u) { return u.Id() === that.EditId(); }); return user; });

tfoot

但是由于您的<tfoot data-bind="if: EditUser() != null"> <!-- ko with: EditUser --> <!-- rest of your html ... --> <!-- /ko --> </tfoot> 方法代码,您将新用户添加到用户列表并执行内联编辑。在这种情况下,您可以从Addtfoot按钮之外的所有内容。