2011-10-27 15 views
8

Firefox rellena un formulario con mi nombre de usuario/contraseña. Esto está usando knockout.js para enlazar la entrada pero no actualizará los valores en este tipo de poblado. ¿Me estoy perdiendo algo decir en una carga de página? Cuando se completa y el usuario acierta los envíos, los valores están en blanco.knockout.js y Firefox Save Passwords en el formulario de inicio de sesión

(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 necesita para manejar el evento 'input'. – SLaks

Respuesta

5

La forma en que me he ocupado de esto en el pasado es utilizar un envoltorio a la value vinculante que inicializa el valor del valor actual del elemento.

Se vería así (éste se simplifica para trabajar solamente con los observables):

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 
}; 

Por lo tanto, se utiliza en lugar de valueWithInitvalue. Solo debe asegurarse de que no se invoque ko.applyBindings antes de que la autocompleta haya podido hacer su trabajo.

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

+0

¡Interesante, pero funcionó, gracias! setTimeout (function() {ko.applyBindings (app.viewModel);}, 1000); –

+0

Yo quería construir sobre esto. Si tiene dos credenciales guardadas para el mismo formulario, entonces esto no funciona. Cuando elige un nombre de usuario, rellena la contraseña, pero la contraseña no se refleja en el modelo de vista. Tienes que eliminarlo manualmente y escribirlo. –

+0

Lo tengo que trabajar con esto a continuación con solo volver a vincularlo. app.viewModel.login.userName.subscribe (function() { ko.applyBindings (app.viewModel); }); –

3

he encontrado la solución a este problema no es realmente satisfactoria. Aunque el enfoque es bastante interesante, falla cuando el usuario elige la cuenta más adelante y el navegador permite usar las credenciales almacenadas (por ejemplo, si hay más de una credencial almacenada). También falló cuando comenzó a escribir la contraseña y se eliminó para volver a la contraseña original (al menos en Firefox). Además, realmente no me gustó el tiempo de espera para darle tiempo al navegador, simplemente no es tan bueno.

Mi solución: que no es realmente una, pero pensé que comparto, no obstante

actualización de nuestro modelo simple de forma manual antes de hacer el login en la devolución de llamada presentar. Usando jQuery, algo así como self.password($("#password").val()) debería hacerlo.

De forma alternativa, al usar los enlaces existentes, la activación de un evento de cambio también parece funcionar, p. Ej. $("#password").change().

Los Pros:

  • es sólo para los campos de credenciales, por lo que, probablemente, una cosa de tiempo para su sitio
  • es sencillo y limpio - una o dos líneas en el lugar adecuado
  • parece siempre funcionar de forma fiable, independientemente del navegador, la configuración de credenciales o patrón de uso

Los contras:

  • se rompe una vez más la buena separación Knockout.js proporciona
  • no es una solución sino más bien una solución

voy a seguir con eso por ahora, porque lo encontré trabajo simplemente fiable. Sería bueno decirle a Knockout que reevalúe los enlaces directamente en lugar de almacenar el valor de nuevo manualmente o desencadenarlo a través del evento de cambio. Pero no he encontrado nada hasta ahora.

Simplemente pensando un poco más adelante - el mismo problema debería surgir cuando el navegador completa automáticamente cualquier forma (ej. Como una dirección) - lo que significa que algún tipo de función general haciendo lo anterior sería agradable (probablemente llamando al gatillo de cambio en cada campo de entrada del formulario)

Editar: Algunos código rápido que demuestra la idea

el 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> 

Y el 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

Sólo por alguna información extra:

En la plantilla 5 SPA .NET MVC lo mismo está sucediendo.

me fijo reasignando los valores de entrada a los observables justo antes del inicio de sesión se exectuted:

en login.viewmodel.js

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

    //original 
Cuestiones relacionadas