@romaro

Как поменять состояния инстанса из коллбека?

Пытаюсь написать контрол, который проверяет пароль. По мере ввода текста под инпутом должны будут отмечаться надписи, для которых условия выполнены. При этом пользователь не может отправить форму, пока пароль не соответствует всем критериям.

Я не могу понять, как реализовать метод isPasswordValid() класса passwordChecker, который должен возвращать true, если все ивены, повещенные на поле с паролем, вернули true при последнем срабатывании. То есть как мне "опросить" эти ивенты или сохранить их результат в контексте инстанса passwordChecker?

Первое, что пришло в голову, это заготовить переменные в конструкторе класса passwordChecker для каждой проверки. Но значения этих переменных я не могу менять из функций проверки, т.к. они вызываются коллбеками в методе stream другого класса.

Смотреть в сторону bind или мой подход в корне не верный?

Весь JS-код:
class passwordControl {
        constructor(el) {
            this.el = el;
            this.toggleContainer = this.el.querySelector('.toggle-password-mask');
            this.inputElement = this.el.querySelector('input');
            this.closedEye = 'M11.949 2.578L13.527 1A1.041 1.041 0 1115 2.473L2.473 15A1.041 1.041 0 111 13.527l1.409-1.409C.823 10.566 0 8.707 0 8c0-1.302 2.698-6.512 8-6.512 1.536 0 2.853.437 3.949 1.09zm2.573 2.314C15.505 6.167 16 7.442 16 8c0 1.302-2.791 6.512-8 6.512a7.452 7.452 0 01-2.626-.472l2.331-2.331a3.731 3.731 0 004.004-4.004l2.813-2.813zm-4.735-.153A3.688 3.688 0 008 4.279 3.731 3.731 0 004.279 8c0 .647.167 1.256.46 1.787l1.319-1.318A1.931 1.931 0 016 8c0-1.143.857-2 2-2 .163 0 .321.019.471.056l1.316-1.317z';
            this.openedEye = 'M8 1.488c-5.302 0-8 5.21-8 6.512 0 1.302 2.791 6.512 8 6.512S16 9.302 16 8c0-1.302-2.698-6.512-8-6.512zm0 10.233A3.731 3.731 0 014.279 8 3.731 3.731 0 018 4.279 3.731 3.731 0 0111.721 8 3.731 3.731 0 018 11.721zM8 6c1.143 0 2 .953 2 2 0 1.143-.952 2-2 2-1.143 0-2-.952-2-2 0-1.142.857-2 2-2z';
            this.toggleContainer.addEventListener('click', () => {
                this.changeMask();
            });
            this.isHidden = true;
        }
        changeMask() {
            const svgPath = this.el.querySelector('path');
            if (this.isHidden) {
                svgPath.setAttribute('d', this.closedEye);
                this.inputElement.setAttribute('type', 'text');
                this.isHidden = false;
            } else {
                svgPath.setAttribute('d', this.openedEye);
                this.inputElement.setAttribute('type', 'password');
                this.isHidden = true;
            }
        }

        stream(cb) {
            this.inputElement.addEventListener('input', () => cb(this.inputElement.value));
        }
    }

    class passwordChecker {
        constructor(el, passwordControlInstance) {
            this.el = el;
            this.passwordControlInstance = passwordControlInstance;

            function minLengthChecker(value) {
                const minLength = 5;
                // Здесь нужно менять флаг this.isMinLengthChecked
            }

            function upperCaseChecker(value) {
                // Здесь аналогичная проверка
            }

            this.passwordControlInstance.stream(minLengthChecker);
            this.passwordControlInstance.stream(upperCaseChecker);
        }
        isPasswordValid() {
            // ???
        }
    }

    // Контрол пароля
    const userPasswordField = document.querySelector('.js-fieldName_userPassword');
    const passwordControlInstance = new passwordControl(userPasswordField);

    // Контрол чекинга пароля
    const passwordCheckerControl = document.querySelector('.js-passwordChecker');
    const passwordCheckerControlInstance = new passwordChecker(passwordCheckerControl, passwordControlInstance);


И HTML формы:
<h1 class="cell-title">Ваш пароль</h1>
<fieldset class="cell-form-step-1 grid-step1">
    <div class="cell-step-1-message">
        <p>Придумайте надежный пароль для входа в личный кабинет</p>
    </div>
    <div class="style-textbox cell-user-password js-fieldName_userPassword">
        <input type="password" required>
        <label>Пароль</label>
        <div class="toggle-password-mask">
            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
                <path fill-rule="evenodd"
                    d="M8 1.488c-5.302 0-8 5.21-8 6.512 0 1.302 2.791 6.512 8 6.512S16 9.302 16 8c0-1.302-2.698-6.512-8-6.512zm0 10.233A3.731 3.731 0 014.279 8 3.731 3.731 0 018 4.279 3.731 3.731 0 0111.721 8 3.731 3.731 0 018 11.721zM8 6c1.143 0 2 .953 2 2 0 1.143-.952 2-2 2-1.143 0-2-.952-2-2 0-1.142.857-2 2-2z">
                </path>
            </svg>
        </div>
    </div>
    <div class="style-password-checker cell-password-checker js-passwordChecker">
        <ul>
            <li class="js-minLengthChecker">Минимум 8 символов</li>
            <li class="js-upperCaseChecker">Хотя бы одна заглавная буква</li>
            <li class="js-digitChecker">Хотя бы одно число</li>
            <li class="js-specialCharChecker">Любой спец-символ</li>
        </ul>
    </div>
    <button class="cell-btn-send js-btnSend" onclick="return false;" disabled>Создать аккаунт</button>
</fieldset>
<fieldset class="cell-form-step-fin grid-form-step-fin" hidden>
    <div class="cell-fin-message">
        Пароль установлен! Теперь вы можете использовать его для входа в личный кабинет.
    </div>
    <a href="/" class="cell-btn-link-to-auth">Перейти в почту</a>
</fieldset>
<fieldset class="cell-form-step-err grid-form-step-err" hidden>
    <div class="cell-err-message"></div>
</fieldset>
  • Вопрос задан
  • 64 просмотра
Решения вопроса 1
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
Делать колбэки стрелочными функциями:
// так:
    class passwordChecker {
        constructor(el, passwordControlInstance) {
            this.el = el;
            this.passwordControlInstance = passwordControlInstance;
            this.isMinLengthChecked = false;

            const minLengthChecker = (value) => {
                const minLength = 5;
                this.isMinLengthChecked = value.length >= minLength;
            }

            const upperCaseChecker = (value) => {
                // ...
            }

            this.passwordControlInstance.stream(minLengthChecker);
            this.passwordControlInstance.stream(upperCaseChecker);
        }
        isPasswordValid() {
            // ???
        }
    }


Помимо этого, в качестве DOM listener'а может выступать не только функция, но и объект с таким интерфейсом: https://developer.mozilla.org/ru/docs/Web/API/Even...
и в его методе handleEvent, который будет вызван по событию, this будет сам этот объект
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
16 мая 2024, в 23:36
200000 руб./за проект
16 мая 2024, в 23:10
12000 руб./за проект