Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iuap design 源码分析系列-双MVVM模型 #23

Open
bluemind7788 opened this issue Jun 27, 2016 · 0 comments
Open

iuap design 源码分析系列-双MVVM模型 #23

bluemind7788 opened this issue Jun 27, 2016 · 0 comments

Comments

@bluemind7788
Copy link

分析1 何谓双MVVM

现在已经有很多流行的MVVM框架,如knockout、vue、angular、avalon等,它们都实现了普通的html元素与简单数据(包括基本数据类型和数组)的双向绑定。但是在View层,除了普通的html元素,还有很多js插件,它们是在js代码中通过拼接html的方式渲染出来的前端展示,如很多的jquery插件;在Model层,简单的数据在一些场景下会有些力不从心,如knockout的数组,改变数组的一行中某列的值,View层并不能更新;列的元信息如字段名、校验规则等并不能在数组结构中表示;数组数据的选中行等统计信息,只能在数组外添加计算属性实现。
双MVVM除了实现普通html元素与简单数据绑定外,还实现了普通html元素与复杂数据、jsView插件与简单数据、jsView插件与复杂数据的绑定。

分析2 双MVVM的实现原理

普通html与简单数据、复杂数据的绑定通过knockout就可以搞定,这是我们的第一种绑定方式。
jsView插件与简单数据、复杂数据的绑定是需要针对每一个jsView插件加入一个中介者,这个中介者实现了数据的监听和控件的监听,当数据发生变化时,中介者会去调用jsView插件提供的api去更新view,当控件发生变化时,会调用复杂数据的api更新数据,这是我们的第二种绑定的实现的基本原理。
两种绑定方式的区别绑定view的粒度不同,一个是html元素级别,一个控件级别。在iuap design中,主要是实现了第二种绑定方式。

分析3 举例说明第二种绑定方式

这种绑定方式的代码在src/model/comp-adp目录下,我们以checkbox.js来分析。先看看简化版的代码

u.CheckboxAdapter = u.BaseAdapter.extend({
    init: function (options) {
        var self = this;
        // 初始化控件
        this.comp = new u.Checkbox(this.element);
        this.element['u.Checkbox'] = this.comp; 
        // 监听控件的变化
        this.comp.on('change', function(){
            var modelValue = self.dataModel.getValue(self.field);
            modelValue = modelValue ? modelValue : '';

            if (self.comp._inputElement.checked) {
                self.dataModel.setValue(self.field, self.checkedValue);
            }else{
                self.dataModel.setValue(self.field, self.unCheckedValue)
            }
        });

        if(this.dataModel){
            // 监听datatable的变化
            this.dataModel.ref(this.field).subscribe(function(value) {
                self.modelValueChange(value)
            })
        }
    },
    modelValueChange: function (val) {
        var self = this;
        if (this.comp._inputElement.checked != (val === this.checkedValue)){
            this.comp.toggle();
        }
    }
})

可以看到通过new u.Checkbox(this.element)进行了控件的初始化;this.comp.on('change', function(){...})实现了控件的监听,监听的回调方法中通过self.dataModel.setValue(self.field, self.checkedValue)进行了复杂数据datatable的改变; this.dataModel.ref(this.field).subscribe(function(value) {
self.modelValueChange(value)
})实现了复杂数据的监听,在监听函数modelValueChange中通过this.comp.toggle()`对控件进行了更新。

未完待续

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant