如何将回调函数传递给已编译的Jade模板,而无需在javascript中全局声明它

时间:2015-09-02 07:00:28

标签: javascript twitter-bootstrap backbone.js pug backgrid

我创建了一个Backgrid表来管理用户。该表的一个功能是允许管理员更改密码。这是通过向backgrid表添加一个按钮单元格列来启动模式更改密码对话框来实现的。输入密码并单击更改后,新密码将传递回backgrid单元格并插入回调中的主干模型。

问题是传递回调,因为更改密码对话框是编译的客户端Jade模板,所以当呈现html时我无法在选项中传递函数,我只能传递一个函数名。

这是我到目前为止(仅显示Jade和Backgrid PasswordCell定义)。

客户端Jade模板:

#user-passwd-dialog.modal
.modal-dialog
    .modal-content
        .modal-header.bg-warning
            button.close(type="button" data-dismiss="modal" aria-label="Close")
                span(aria-hidden="true") ×
            h4.modal-title
                span.glyphicon.glyphicon-log-in
                span  Set User Password
        .modal-body
            if message.length > 0
                // show any messages that come back with authentication
                .alert.alert-info #{message}

            // LOGIN FORM
            form
                .form-group
                    label(for="user-password") Password
                    input.form-control#user-password(type="password" placeholder="New Password")
                .form-group
                    label(for="user-confirm") Confirm Password
                    input.form-control#user-confirm(type="password" disabled="disabled" placeholder="Confirm Password")

        .modal-footer
            button.btn.btn-warning.btn-lg#user-change-password(type="button" disabled="disabled") Change Password
            button.btn.btn-warning.btn-lg(type="button" data-dismiss='modal') Cancel

script(type="text/javascript").
    function checkMatch() {
        var password = $("#user-password").val();
        var confirmPassword = $("#user-confirm").val();

        if (password !== confirmPassword) {
            $("#user-confirm").removeClass("alert alert-success").addClass("alert alert-danger");
            $("#user-change-password").prop("disabled", true);
            return false;
        } else {
            $("#user-confirm").removeClass("alert alert-danger").addClass("alert alert-success");
            $("#user-change-password").prop("disabled", false);
            return true;
        }
    }
    $("#user-password").keyup(function() {
         var password = $("#user-password").val();
         if (password.length >= #{ minLen }) {
             $("#user-confirm").prop("disabled", false);
            checkMatch();
        } else { 
            $("#user-confirm").prop("disabled", true);
        }
    });
    $("#user-confirm").keyup(function() {
        var password = $("#user-password").val();
        if (password.length >= #{ minLen }) {
            checkMatch();
        }
    });
    $("#user-change-password").click(function() {
        var password = $("#user-password").val();
        #{result}(password);
        $('#user-passwd-dialog').modal('hide');
    });

Backgrid单元格定义为(已编译的Jade模板为Templates.set_password(opts)):

    var PasswordCell = Backgrid.Cell.extend({
    className: "button-cell",
    template: function () {
        return '<button class="btn btn-sm btn-warning"><span class="glyphicon glyphicon-lock"></span></button>';
    },
    events: {
        "click": "setPassword"
    },
    setPassword: function (e) {
        e.preventDefault();
        // XXX binding to global variable so modal can set password
        // must be more elegant way to do this
        mycallbackwiththelongname = (function(password) {
            this.model.set({ password : password});
        }).bind(this);
        var opts = {
            message:"The password must be at least 8 characters long",
            minLen: 8,
            result: "mycallbackwiththelongname"
        };
        $("#dialog-wrapper").html(Templates.set_password(opts));
        $("#user-passwd-dialog").modal({ keyboard: true });
    },
    render: function () {
        this.$el.html(this.template());
        this.delegateEvents();
        return this;
    }
});

问题在于代码:是否有更优雅的方式来传递回调,因此不需要全局函数。本地函数更可取,但我不知道如何指定名称。

我有一个使用全局函数的简化jsfiddle

1 个答案:

答案 0 :(得分:0)

我找到了一种方法,通过使用jQuery数据API传递它来使用PasswordCell“click”处理程序的本地函数。我将回调函数附加到父元素,然后将父元素的名称传递给呈现Jade模板的函数。

在PasswordCell中将setPasswd更改为:

    setPassword: function (e) {
        e.preventDefault();
        var passwordResult = (function(password) {
            this.model.set({ password : password});
        }).bind(this);
        var opts = {
            name: "change-password-modal",
            message:"The password must be at least 8 characters long",
            minLen: 8,
            parent: "dialog-wrapper"
        };
        $("#dialog-wrapper").html(Templates.set_password(opts));
        $("#dialog-wrapper").data("onChange", passwordResult);
        $("#user-passwd-dialog").modal({ keyboard: true });
    },

在Jade模板中更改按钮单击事件处理程序:

$("#user-change-password").click(function() {
    var password = $("#user-password").val();
    $("##{ parent }").data("onChange")(password);
    $('#user-passwd-dialog').modal('hide');
});

jsfiddle已更新。