Tak wygląda mój kod (całkowicie)

function getPassword() {
    let pwd = ($('<input/>', {
   //unrelated code
    })).on('blur', function() {
        //more unrelated code
        } else {
            $(this).css({
                'color': 'gray',
                'border': '1px solid green'
            });
            let cValue = $(this).val();
            console.log(cValue);
            let x = getPasswordConfirm(cValue);
        }
    });
    return pwd;

}

function getPasswordConfirm(cValue) {
    let pwd = ($('<input/>', {
        //more unrelated code
    })).on('blur', function() {
        //unrelated code
        } else {
            if ($(this).val() !== cValue) {
                    console.log(cValue);
//this is where it goes wrong, cValue is undefined???
            } else {
                $(this).css({
                    'color': 'gray',
                    'border': '1px solid green'
                });
                console.log(cValue);
            }
        }
    });
    return pwd;
}

Problem, który mam, jest: używam cValue jako argumentu, ale nie zostanie przekazany do mojej funkcji. Po konsolę.log {x1}} powraca niezdefiniowany w funkcji My {X2}}. Aby powiększyć część, w której dzwonię do funkcji i spróbuj przekazać argument parametru:

else {
                $(this).css({
                    'color': 'gray',
                    'border': '1px solid green'
                });
                let cValue = $(this).val();
                console.log(cValue); //this works
                let x = getPasswordConfirm('haha');
            }
        });

I jest to część w mojej funkcji, która powinna ocenić bieżącą wartość za pomocą parametru CValue:

 else {
                if ($(this).val() !== cValue) {
                        console.log(cValue); //returns undefined
                } else {
                    $(this).css({
                        'color': 'gray',
                        'border': '1px solid green'
                    });
                    console.log(cValue);
                }

Jak dołączę / zadzwoń do funkcji:

$(getEblock('col-md-6 col-md-offset-3').append(getLoginName(), getUsrName(), getPassword(), getPasswordConfirm()).appendTo('form'));

Ale bez względu na to, czego używam jako argument, zawsze zwraca niezdefiniowany w funkcji My {X0}}. Tak, wywołuję funkcje (jak widać).

1
user9689724 5 czerwiec 2018, 14:31

3 odpowiedzi

Najlepsza odpowiedź

Proszę mi uwierzyć, poprzednia odpowiedź była właściwym sposobem na przejście, ale jeśli chcesz wypróbować własny przepływ, oto rozwiązanie, będzie wolniejsze, wiele niechcianych zmiennych, tak wiele kodowania itp. Możesz grać z kodem z Jsbin

// declare global
// getting form by id (jquery), 
// it is always good practise to define your element in global scope
// we used $somename for jquery specific names
// remember $('somekelement') is a heavy function of jQuery 
// which did lots of calculation behind the scene
// this is why i am declaring it only once 
// it will help me to not used $('#myform') every time, need to access form 
var $myform = $('#myform');

// for your logic i wanted two extra boolean to check if my password and confirm_password i created or not.
var isPassword = false; // by default not created
var isConfirmPassword = false; // false means not created true means created.

// this is your function that create a input and some logic as per your requirements
function getPassword() {

  if(!isPassword) {
    let pwd = $('<input/>', {
          type:'text',
          name:'password',
         'placeholder':'Password'
       }).on('blur', function() {

          if(false) {
            //more unrelated code
          } else {
            $(this).css({
                'color': 'gray',
                'border': '1px solid green'
            });
            let cValue = $(this).val();

            console.log("Your cValue: "+ cValue); // here you are getting your values right.

            let x = getPasswordConfirm(cValue);   // here you are calling another function that generate another input
          }
        });
      return pwd;
      isPassword = true;
    }
};


// if this function is generating new input, then it must not be called inside of getPassword function, because blur event may occur multiple times and each blur will create new confirm_password fields
// here i think logically not possible, 
// only possible way here is to distribute your coding into two section
// 1st section will build all your dynamic input fields
// 2nd section will validate your inputs.
function getPasswordConfirm(cValue) {
  window.cValue = cValue; // i saved cValue here in global namespace so next time.
    console.log('argument cValue: '+cValue); // wola, you got the value here.

  // but sadly, you didn't have c_pwd yet, so you couldn't be able to fire blur event here.
  // Your blur event will be created but if will fire on out of focus, but next time cValue will not be passed
  // because it will happened only one time or you will have multiple inputs each trying to catch a event before born to the world
  if(!isConfirmPassword) {
    let c_pwd = ($('<input/>', {  // changed name to c_pwd
       type:'text',
       name:'confirm_password',
      'placeholder':'Confirm Password'
    })).on('blur', function() {
      console.log('What was cValue: '+ window.cValue);
        if(false) {
            //unrelated code
        } else {
            if ($(this).val() !== cValue) {
                    console.log('====rock you got cValue here : '+cValue); // getting this value here as well. but problem is that you are getting multiple inputs
                //this is where it goes wrong, cValue is undefined???
            } else {
                $(this).css({
                    'color': 'gray',
                    'border': '1px solid green'
                });
                console.log(cValue);
            }
        }
    }.bind(this)); // you can also bind your subscope to their parent scope by bind funciton, in new ES6 we create arrow function (arg1, arg2) => {console.log(arg1,arg2);}

    isConfirmPassword = true;

    //return c_pwd; // comment this line and uncomment next line see result by yourself. 
    $myform.append(c_pwd); // i am appending confirm_password input on blur on password result will create multiple confirm boxes   
  }
};


$myform.append(getPassword());

// suppose your two function build your form then code for appending will be like that
//$myform.append(getPassword()).append(getPasswordConfirm());
1
sorabh86 21 październik 2018, 17:22

Sugerowałbym, aby utrzymać luźno sprzężoną strukturę, co próbujesz zrobić. Proponuję więc przekazać kontekst do wszystkich metod, aby śledzić i interakcję. W razie potrzeby można również użyć tego kontekstu do gromadzenia danych formularzy lub innych celów.

let context = {}
$(getEblock('col-md-6 col-md-offset-3').append(
  getLoginName(context),
  getUsrName(context),
  getPassword(context),
  getPasswordConfirm(context)
).appendTo('form'));

function getPassword(context) {
  let pwd = ($('<input/>', {
    //unrelated code
  }))
  .on('blur', function() {
    //more unrelated code
    context.cValue = $(this).val();
  });
  return pwd;
}

function getPasswordConfirm(context) {
  let pwd = ($('<input/>', {
    //more unrelated code
  }))
  .on('blur', function() {
    if ($(this).val() !== context.cValue) {
      //password mismatch
    }
  });
  return pwd;
}
0
Munim Munna 21 październik 2018, 17:40

Problem polega na tym, że tworzysz koncert zdarzeń wewnątrz Twojej funkcji (którego nie powinieneś, jeśli dzwonisz do funkcji więcej niż raz, ale to kolejna historia). Zanim utworzysz program obsługi, 'cValue' jest zdefiniowany. Ale po utworzeniu procedury obsługi, funkcja wyjściowa (zrobiła to praca). Następnie po wystąpieniu zdarzenia 'cValue' nie jest już zdefiniowane (ponieważ funkcja zewnętrzna od dawna wykończona, a {x2}} jest zebrane śmieci.

Rozwiązaniem problemu może być, że zewnętrzna funkcja przechowuje wartość cValue w global variable. W przypadku wystąpienia zdarzenia, grapuj tę globalną zmienną, insdie Eventhandler i używa go.

0
Poul Bak 20 październik 2018, 17:23