2011-10-27 44 views
8

Firefox使用我的用户名/密码填充表单。这是使用knockout.js绑定输入,但它不会更新这种填充的值。我在页面加载时错过了什么吗?当它填充并且用户点击提交时,值为空。knockout.js和Firefox在登录表单上保存密码

(function (app, $, undefined) { 

    app.viewModel = app.viewModel || {}; 
    app.login = {}; 

    app.viewModel.login = { 
     userName: ko.observable(''), 
     password: ko.observable(''), 
     returnUrl: '' 
    }; 

    app.viewModel.login.submit = function() { 
     sso.login(app.viewModel.login.userName(), app.viewModel.login.password(), app.viewModel.login.returnUrl); 
    }; 

    app.login.init = function (returnUrl) { 

     app.viewModel.login.returnUrl = returnUrl; 

     ko.applyBindings(app.viewModel); 
    }; 

})(window.app = window.app || {}, jQuery); 
+0

Knouckout.js需要处理'input'事件。 – SLaks

回答

5

,我已经在过去处理这个问题的方法是使用一个包装的value绑定初始化一个元素的当前值的值。

它看起来像(这一个被简化为只工作,观测):

ko.bindingHandlers.valueWithInit = { 
    init: function(element, valueAccessor, allBindingsAccessor, context) { 
     var observable = valueAccessor(); 
     var value = element.value; 

     observable(value); 

     ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor, context); 
    }, 
    update: ko.bindingHandlers.value.update 
}; 

所以,你可以使用valueWithInit,而不是value。您只需确保在自动完成功能能够完成其工作之前不调用ko.applyBindings。

http://jsfiddle.net/rniemeyer/TeFAX/

+0

有趣,但它工作,谢谢! setTimeout(function(){ko.applyBindings(app.viewModel);},1000); –

+0

我想建立在此基础上。如果您有两个保存的相同表单的凭据,则这不起作用。当你选择一个用户名时,它会填充密码,但密码不会反映在视图模型中。你必须手动删除它,并输入它。 –

+0

我只是重新绑定它,以解决它。 app.viewModel.login.userName.subscribe(function(){ ko.applyBindings(app.viewModel); }); –

3

我找到了解决办法在这里没有真正令人满意。虽然这种方法非常有趣,但当用户稍后选择帐户并且浏览器允许使用存储的凭证时(例如,如果存在多个凭证),它就会失败。当你开始输入密码并删除回到原始密码(至少在Firefox中)时,它也失败了。 此外,我真的不喜欢超时给浏览器时间 - 只是不那么好。

我的解决办法: 这是不是真的,但我认为在提交回调做登录之前手动我仍然共享

简单的更新我们的模型。 使用jQuery,像self.password($("#password").val())应该这样做。

或者,使用现有的绑定,触发更改事件似乎也可以工作 - 例如, $("#password").change()

的优点:

  • 仅供证书字段,因此可能为您的网站一次的事情
  • 是简单,干净 - 一个或者在适当的位置两行
  • 似乎总可靠的工作,不管是什么浏览器,证书安装或使用模式

的缺点:

  • 休息再漂亮的分离Knockout.js提供
  • 是不是一个解决方案,而是一种变通方法

我将与坚持,现在因为我发现它只是工作可靠。很高兴告诉Knockout直接重新评估绑定,而不是手动存储值或通过更改事件触发它。但到目前为止我还没有发现任何东西。

只是想一下 - 当浏览器自动完成任何形式(例如地址)时,应该会出现同样的问题 - 这意味着执行上述操作的某种通用函数会很好(可能调用更改触发器在表格的每个输入字段)

编辑: 一些快速代码演示的想法

的HTML:

<form id="myForm" data-bind="submit: login"> 
    Email: <input type="text" data-bind="value: email" /><br/> 
    Password: <input type="password" data-bind="value: password" /><br/> 
    <button type="submit">Login</button> 
</form> 

和JavaScript:

function ViewModel() { 
    var self = this; 

    self.email = ko.observable(""); 
    self.password = ko.observable(""); 

    self.login = function() { 
     $("#myForm").find("input").change(); 

     //Now the observables contain the recent data 
     alert(ko.mapping.toJSON(self)); 
    }; 
} 
0

只是一些额外的信息:

在.NET MVC 5 SPA模板,同样的事情正在发生。

我固定它通过重新分配的输入值观测登录被exectuted之前:

login.viewmodel.js

// Operations 
self.login = function() { 
    self.userName($("#LoginUserName").val()); 
    self.password($("#LoginPassword").val()); 

    //original