MVVM架构是什么?
Model-View-ViewModel,也就是MVVM架构是由MVP模式与WPF结合的应用方式发展演变过来的一种新型架构框架,立足于原有MVP框架并且糅合了WPF的新特性,MVVM 的核心是 ViewModel 层,负责转换 Model 中的数据对象来让数据变得更容易管理和使用,该层向上与视图层进行双向数据绑定,向下与 Model 层通过接口请求进行数据交互,起呈上启下作用。
模型示意图
模型还是根据主流的设计思路,使用分层设计的理念
分为View层,Model层以及ViewModel层
View层
视图层,也就是用户界面,主要由 HTML 和 CSS 来构建,而为了更方便地展现ViewModel层和Model层的数据,产生了很多前后端模板语言。许多的MVVM 框架如 KnockoutJS,Vue,Angular 等也都有自己用来构建用户界面的内置模板语言。
Model层
泛指后端进行的各种业务逻辑处理和数据操控,主要围绕数据库系统展开。
ViewModel层
ViewModel 层是由前端开发人员组织生成和维护的视图数据层。ViewModel 层所封装出来的数据模型包括视图的状态和行为两部分,而 Model 层的数据模型是只包含状态的,而实际上我们平时生活中能够见到的View层,所获得的的数据是来自于ViewModel层,并非是Model层的数据,因此ViewModel类似于是一个中间商的作用,购房者所想要买到合适的房源,依赖的是中间商提供的信息,和房屋主没有任何的直接联系。
MVVM框架的主要应用场景
1)针对具有复杂交互逻辑的前端应用
2)提供基础的架构抽象
3)通过Ajax数据持久化,保证前端用户体验
简单介绍一下关于Ajax方面的内容,Ajax是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术,也就意味着他能够提高搜索的效率,利用更少的资源获取到相同的可用信息。
这样MVVM的效益就体现出来了,能够很好地与Ajax进行结合,减少刷新整张页面,提高资源的利用率。
代码示例
Model
{"weatherinfo":{"city":"杭州","cityid":"101210101","temp1":"5℃","temp2":"20℃","weather":"晴转多云","img1":"n0.gif","img2":"d1.gif","ptime":"18:00"}} public class WeatherData { private WeatherInfo weatherinfo; public WeatherInfo getWeatherinfo() { return weatherinfo; } public void setWeatherinfo(WeatherInfo weatherinfo) { this.weatherinfo = weatherinfo; } } public class WeatherInfo { private String city; private String cityid; private String temp1; private String temp2; private String weather; private String img1; private String img2; private String ptime; public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getCityid() { return cityid; } public void setCityid(String cityid) { this.cityid = cityid; } public String getTemp1() { return temp1; } public void setTemp1(String temp1) { this.temp1 = temp1; } public String getTemp2() { return temp2; } public void setTemp2(String temp2) { this.temp2 = temp2; } public String getWeather() { return weather; } public void setWeather(String weather) { this.weather = weather; } public String getImg1() { return img1; } public void setImg1(String img1) { this.img1 = img1; } public String getImg2() { return img2; } public void setImg2(String img2) { this.img2 = img2; } public String getPtime() { return ptime; } public void setPtime(String ptime) { this.ptime = ptime; }
ModelView
public class QueryWeatherViewModel { private static final String TAG = "QueryWeatherViewModel"; public final ObservableBoolean loading = new ObservableBoolean(false); public final ObservableBoolean loadingSuccess = new ObservableBoolean(false); public final ObservableBoolean loadingFailure = new ObservableBoolean(false); public final ObservableField<string> city = new ObservableField<>(); public final ObservableField<string> cityId = new ObservableField<>(); public final ObservableField<string> temp1 = new ObservableField<>(); public final ObservableField<string> temp2 = new ObservableField<>(); public final ObservableField<string> weather = new ObservableField<>(); public final ObservableField<string> time = new ObservableField<>(); private Call<weatherdata> mCall; public QueryWeatherViewModel() { } public void queryWeather() { loading.set(true); loadingSuccess.set(false); loadingFailure.set(false); mCall = RetrofitManager.get() .create(QueryWeatherRequest.class) .queryWeather(); mCall.enqueue(new Callback<weatherdata>() { @Override public void onResponse(Call<weatherdata> call, Response<weatherdata> response) { WeatherInfo weatherInfo = response.body().getWeatherinfo(); city.set(weatherInfo.getCity()); cityId.set(weatherInfo.getCityid()); temp1.set(weatherInfo.getTemp1()); temp2.set(weatherInfo.getTemp2()); weather.set(weatherInfo.getWeather()); time.set(weatherInfo.getPtime()); loading.set(false); loadingSuccess.set(true); } @Override public void onFailure(Call<weatherdata> call, Throwable t) { if (call.isCanceled()) { Log.i(TAG, "call is canceled."); } else { loading.set(false); loadingFailure.set(true); } } }); } public void cancelRequest() { if (mCall != null) { mCall.cancel(); } } }
View
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <data> <import type="android.view.View" /> <variable name="viewModel" type="com.github.cyc.mvvmdemo.weather.viewmodel.QueryWeatherViewModel" /> </data> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:padding="@dimen/default_content_padding" tools:context="com.github.cyc.mvvmdemo.weather.activity.QueryWeatherActivity"> <Button android:id="@+id/btn_query_weather" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:text="@string/query_weather" android:enabled="@{viewModel.loading ? false : true}" android:onClick="@{() -> viewModel.queryWeather()}" /> <RelativeLayout android:id="@+id/vg_weather_info" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/btn_query_weather" android:layout_marginTop="@dimen/query_weather_margin" android:visibility="@{viewModel.loadingSuccess ? View.VISIBLE : View.GONE}"> <TextView android:id="@+id/tv_city" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textStyle="bold" android:text="@string/city" /> <TextView android:id="@+id/tv_city_value" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/tv_city" android:layout_alignBottom="@id/tv_city" android:text="@{viewModel.city}" tools:text="杭州" /> <TextView android:id="@+id/tv_city_id" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/tv_city" android:layout_marginTop="@dimen/query_weather_margin" android:textStyle="bold" android:text="@string/city_id" /> <TextView android:id="@+id/tv_city_id_value" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/tv_city_id" android:layout_alignBottom="@id/tv_city_id" android:text="@{viewModel.cityId}" tools:text="101210101" /> <TextView android:id="@+id/tv_temp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/tv_city_id" android:layout_marginTop="@dimen/query_weather_margin" android:textStyle="bold" android:text="@string/temperature" /> <TextView android:id="@+id/tv_temp1_value" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/tv_temp" android:layout_alignBottom="@id/tv_temp" android:text="@{viewModel.temp1}" tools:text="5℃" /> <TextView android:id="@+id/tv_tilde" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/tv_temp1_value" android:layout_alignBottom="@id/tv_temp" android:text="@string/tilde" /> <TextView android:id="@+id/tv_temp2_value" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/tv_tilde" android:layout_alignBottom="@id/tv_temp" android:text="@{viewModel.temp2}" tools:text="10℃" /> <TextView android:id="@+id/tv_weather" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/tv_temp" android:layout_marginTop="@dimen/query_weather_margin" android:textStyle="bold" android:text="@string/weather" /> <TextView android:id="@+id/tv_weather_value" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/tv_weather" android:layout_alignBottom="@id/tv_weather" android:text="@{viewModel.weather}" tools:text="晴" /> <TextView android:id="@+id/tv_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/tv_weather" android:layout_marginTop="@dimen/query_weather_margin" android:textStyle="bold" android:text="@string/release_time" /> <TextView android:id="@+id/tv_time_value" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/tv_time" android:layout_alignBottom="@id/tv_time" android:text="@{viewModel.time}" tools:text="10:00" /> </RelativeLayout> <ProgressBar android:id="@+id/pb_progress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:visibility="@{viewModel.loading ? View.VISIBLE : View.GONE}" /> <TextView android:id="@+id/tv_query_failure" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="@string/query_failure" android:visibility="@{viewModel.loadingFailure ? View.VISIBLE : View.GONE}" /> </RelativeLayout> </layout>部分参考自https://www.2cto.com/kf/201805/745059.html 点击打开链接