2011-10-27 78 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