javascript - Form validation when using flux -


i using flux in application use backbone.view view layer.

generally there store instance whole page, store save data(or state) of application, , view listener change event of store, when store trigger change event, view re-render accordingly.

so far good, meet problems when use form, when use try submit form or blur event triggered element, want validate input in server , display errors possible, have done:

  1. when user hit submit button or value changed element,i dispatch action like: dispatch({type:"validate",value:"value"});

  2. the store respond action , send request server

  3. when response back,i update store , trigger change event: store.validate_response=response; store.trigger("change");

  4. the view(form in example) re-render itself.

i can display errors can not keep value of element since elements in form re-rendered means display origin value rather value user typed.

i have thought save typed values when dispatch validate action this:

dispatch({type:"validate",value:"value",usertypedvalueforeveryelement:"....."}); 

it works when use hit submit button, since when hit button not type in form, how situation:

<input type="text" id="a" /> <input type="text" id="b" /> 

user type avalue in input a, type bv in input b, @ same time validation, , send both value when dispatch action:

{a:"avalue",b:"bv"} 

the store keep these values.

and during request, user keep typing element b, value bvalue, , @ same time validation response returned, form re-render, , set avalue a , bv b, point, value of b lost, user surprised, not know happened.

any idea fix that?

it seems flux manner:

view trigger action -->  store respond actions -->  store trigger changed --> view respond store(re-render in case) -->  view trigger action"  

make kind of requirement complex before. have more job keep state of view once there interactive view.

is true or beacuse miss anything?

it sounds have few different issues in play here, they're solvable. little long, addresses issues you're running into.

store design: first, information store meant hold? try not think of flux store backbone model, because purposes aren't quite same. flux store should store part of application's state (not part of ui component's state), , shouldn't know or care views using it. keeping in mind can put behavior , data in right places. let's store keeping track of user's input specific form. since application cares whether input valid or not, need represent in store somehow. represent each input object in store, {val: 'someinput', isvalid: false}. store it, has there; part of app should able pull data store , know input valid/invalid.

i agree @korven putting lots of application logic in stores poor choice. put ajax calls action creation logic, ajax response callbacks creating actual actions on dispatcher; i've seen recommended more once.

preserving user input: one, want render form inputs when user has finished typing - otherwise, render change text they're typing it. that's easy enough -- throttle or debounce (debounce preferable here) input validation handler user input events. (if you're using focus or blur events, timing less issue, should still consider it.) have store update after validation done. and, of course, render when store updates. modify input's value in dom when user has stopped typing , have validated input.

even throttling/debouncing, since validation requests async , user (potentially) trigger many validation requests in short period of time, can't rely on responses coming in order. in other words, can't process each response come back; if come out of order you'll overwrite recent input old input. (i've run in real life. may edge case when happens bug confusing enough it's worth addressing front.) fortunately, care most recent thing user typed. can ignore responses our validation requests except response recent request. can integrate logic whatever makes requests keeping track of 'key' each request. here's example of how i've solved this:

// in view this.on(keyup, function() {   var input = this.getuserinput();   validationservice.validate(input); }  // within validationservice validate: function(input) {   // generate random int between 1 , 100   var randkey = math.floor(math.random() * (100 - 1)) + 1;   this.lastrequestkey = randkey;   this.doajaxrequest({     data: {input: input},     callback: function() {       if (randkey !== this.lastrequestkey) {         // newer request has modified this.lastrequestkey         return;       }       // update store    }); } 

in example, object responsible validation service 'remembers' set 'key' request. each callback has original key in scope closure, , can check if original key equals 1 set on service object. if not, means request has happened, , no longer care response. you'll want 'keys' set per-field, new request field b doesn't override older request field a. can solve in other ways, point is, discard last request's response given input. has added bonus of saving update/render cycles on discarded responses.

multiple fields rendering: when you're doing flux right, should never 'lose' data because changes come dispatcher/store, , because dispatcher won't send new update stores until previous update finished. long update store each new input, won't lose anything. don't have worry change input b causing lose change input in progress, because change input flow dispatcher store view and finish rendering before dispatcher allow change input b begin processing. (that means renders should fast, they'll block next operation. 1 of reasons react goes w/flux.)

as long put store -- , don't put wrong thing store, input , async handling stuff above addresses -- ui accurate. flux pattern treats each change atomic transaction that's guaranteed complete before next change occurs.


Comments

Popular posts from this blog

Hatching array of circles in AutoCAD using c# -

ios - UITEXTFIELD InputView Uipicker not working in swift -

Python Pig Latin Translator -