为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 MVVM 正确验证登录表单?

如何使用 MVVM 正确验证登录表单?

蓝山帝景 2023-04-13 16:58:49
当Android主要模式是MVP我们将验证逻辑存储在presenters(因为view应该是愚蠢的- 如果我错了请纠正我)因为一个presenter只适用于一个view。InMVVM ViewModel不知道View哪个使用了 thisViewModel和(据我了解)aViewModel可以被不同的人使用Views而不会违反MVVM想法。所以,问题是在哪里验证登录表单MVVM?意识形态上正确的解决方案是什么?
查看完整描述

2 回答

?
慕后森

TA贡献1802条经验 获得超5个赞

我在 android 中看到过很多MVVM模式的实现。我在我的项目中遵循以下结构。我不知道这是否理想。如果错了请纠正我。

首先让我回答你的问题,

在哪里验证 MVVM 中的登录表单?

我在中进行验证ViewModel

class LogInViewModel : ViewModel() {


    ...


    fun performValidation() {


        if (username.isBlank()) {

            logInResult.value = "Invalid username"

            return

        }


        if (password.isBlank()) {

            logInResult.value = "Invalid password"

            return

        }


        logInResult.value = "Valid credentials :)"

    }


}

意识形态上正确的解决方案是什么?

正如我所说,我们可以遵循许多结构在 android 中实现 MVVM。下面给出了我如何做的例子。代码中充满了注释,所以我相信它是可以自我理解的。无论如何,请随时在评论中要求任何澄清。(为了可读性,我从布局文件中删除了一些代码)

//img4.sycdn.imooc.com/6437c47f0001b90002660588.jpg

登录视图模型


class LogInViewModel : ViewModel() {


    /**

     * Two way bind-able fields

     */

    var username: String = ""

    var password: String = ""


    /**

     * To pass login result to activity

     */

    private val logInResult = MutableLiveData<String>()


    fun getLogInResult(): LiveData<String> = logInResult


    /**

     * Called from activity on login button click

     */

    fun performValidation() {


        if (username.isBlank()) {

            logInResult.value = "Invalid username"

            return

        }


        if (password.isBlank()) {

            logInResult.value = "Invalid password"

            return

        }


        logInResult.value = "Valid credentials :)"

    }


}


登录处理器


/**

 * To pass UI events to activity

 */

interface LogInHandler {


    /**

     * Will be called when login button gets clicked

     */

    fun onLogInClicked()

}

activity_login.xml


<layout>


    <data>


        <variable

            name="viewModel"

            type="com.theapache64.mvvmloginsample.LogInViewModel" />


        <variable

            name="handler"

            type="com.theapache64.mvvmloginsample.LogInHandler" />

    </data>


    <androidx.constraintlayout.widget.ConstraintLayout>


        <EditText

            ...

            android:text="@={viewModel.username}" <!--Two way binding username-->

        />


        <EditText

            ...

            android:text="@={viewModel.password}" <!--Two way binding password-->

        />


        <Button

            ...

            android:onClick="@{()->handler.onLogInClicked()}" <!--Invoked on button click-->

        />

    </androidx.constraintlayout.widget.ConstraintLayout>

</layout>

最后是活动


登录活动


class LogInActivity : AppCompatActivity(), LogInHandler {


    private lateinit var viewModel: LogInViewModel


    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)


        // Binding

        val binding =

            DataBindingUtil.setContentView<ActivityLoginBinding>(this, R.layout.activity_login)


        // ViewModel

        this.viewModel = ViewModelProviders.of(this).get(LogInViewModel::class.java)


        // Setting binding params

        binding.viewModel = viewModel

        binding.handler = this


        // Watching for login result

        viewModel.getLogInResult().observe(this, Observer { result ->

            Toast.makeText(this, result, Toast.LENGTH_SHORT).show()

        })

    }


    override fun onLogInClicked() {

        viewModel.performValidation()

    }


}

我在 GitHub 中托管了完整的源代码。


查看完整回答
反对 回复 2023-04-13
?
FFIVE

TA贡献1797条经验 获得超6个赞

首先,您应该使用双向数据绑定并将文本值分配给视图模型中的可观察字段并使用这样的函数


private fun validateFields(): Boolean {

        if (email.value.isNullOrBlank()) {


            return false

        }

        if (password.value.isNullOrBlank()) {


            return false

        }

        return true

    }

要验证您的字段,您可以根据需要添加更多级别的验证。


然后您可以将以下功能附加到布局中的登录按钮


 fun loginUser() {

        if (validateFields()) {

            val job = viewModelScope.launch(Dispatchers.IO) {

                result.postValue(

                    repo.makeLoginRequest(

                        email = email.value,

                        password = password.value

                    )

                )

           }


        }

    }

并随心所欲地使用结果,这里我使用的是实时数据和协程


检查电子邮件是否有效使用:


private fun isValidEmail(): Boolean = android.util.Patterns.EMAIL_ADDRESS.matcher(email.value).matches()



查看完整回答
反对 回复 2023-04-13
  • 2 回答
  • 0 关注
  • 129 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信