在knockoutjs 上自己实现的flux(实例讲解)

在knockoutjs 上实现 Flux 单向数据流 状态机,主要解决多个组件之间对数据的耦合问题。

一、其实简单

flux的设计理念和实现方案,很大程度上人借鉴和参考了Vuex的实现,只是简化了某些过程,数据流向图如下:

从上图,中以看出数据的改变是单向循环的。我想这就是Flux理念的核心所在吧。Vuex中对Action规范为Action和Mutation,由action去触发Mutation,action是可以异步的,而Mutation则是同步更新。而我在设计ko的Flux时,去掉了Mutation这个环节,是因为我理解为,异步的请求一般情况下都是与api接口有关系,这块内容存在极大的变化性,应该从业务或项目构架上做一层区分。

二、如果使用

当然,flux只是针对knockoutjs的,所以你使用之前必须引入knockoutjs。flux主要的方法和对象

2.1 静态方法

方法方法,当然他必须先与createStore方法调用。方法是有返回值,他的返回值可以调用register方法注册到指定的域上,但第一次调用方法时是创建rootStore(根状态器),他不允许被注册到域的。

2.1.1 flux.createStore参数格式

名称方法,方法的第一个参数为state,第二参数开始则为传入的相关内容获取state上的相关状态数据,当然返回是一个ko监控对象。

2.2 实例方法

createStore方法的执行,会在ko实例上增加$store属性,此属性是状态器的实例对象,在任何位置都可以调用他的dispatch来触发事件。

方法注册一个状态域,域与域之间是相互独立存储的,域之间action或get名称是可以重复的调用指定的action,无返回值调用指定的get,有返回值

三、简单的使用

本示例定义了四个ko绑定区域,分别是:app1,app2,app3,app4。实现app4中对name的改变自动影响到app1,而app3对列表的改变自动影响到app2。

3.1 定义vm并初始化store

viewmodel(){ this.list = ko.observableArray(); this.name = ko.observable('无名氏'); this.count = ko.computed(function(){ //必须用this,这个时候ko.$store还没创建完成,应该ko.computed创建时会执行一次此处 //如果是子vm依赖主vm,还是可以用ko.$store的 return this.list().length + '个数'; //需要对监控对象求值,否则computed不能有效 },this); } var fullVm = new viewmodel(); var index = 1; fullVm.vf={ add: function(){ ko.$store.dispatch('addClass',{title: 'title' + (index++)}); } } var opt = { state: { class: fullVm },actions:{ "setName":function(state,name){ state.class.name(name); },"addClass":function(state,classInfo){ state.class.list.push(classInfo); } },getters:{ "getName":function(state){ return state.class.name; } } } flux.createStore(opt);

根据上述代码,首先定义了viewmodel的一个类,并创建了一个fullVm的一个实例,然后直接在fullVm实例上增加了add方法

opt的state引用的是fullVm,其中还配置了actions和getters相关对象,然后调用flux.createStore(opt)方法。创建一个store,并关联到ko.$store对象上。

3.2 与视图绑定

HTML代码

404_74@
404_74@

  • 添加 404_74@

    js代码:

    四、域的实例

    HTML代码:

    @H_404_74@
    404_74@ 404_74@

    js代码

    viewmodel(){ this.name = ko.observable('root'); } var rVM = new rootviewmodel(); flux.createStore({ state: rVM}); //创建root状态器

    var treeNode={
    name: ko.observable('node'),changeName:function(){
    ko.$store.areas.treeNode.state.name('新名字');
    },full: ko.computed(function(){
    //computed的职责:1. 监控其他对象属性的变化,而影响自身对象(flux解决);2. 合并自身对象的几个属性(在function下,有this可解)
    //不能通过ko.$store访问对象本身,因为首次对象本身还没初始化好
    var store = ko.$store;
    //(store.areas.treeNode? store.areas.treeNode.state.name() : '') 这样也是不行,因为解决第一次通不过,后面肯定不行
    return store.state.name();
    })
    }

    ko.$store.register('treeNode',flux.createStore({ state: treeNode})); //创建子状态机
    var app1 = ko.applyBindings(rVM,document.getElementById("app1"));
    var app2 = ko.applyBindings(treeNode,document.getElementById("app2"));

    五、其他

    当然模块化的引用,也是支持。具体实例细节可参考test中的测试示例。

    项目的git地址:,欢迎大家指正和提出宝贵的意见。

    以上这篇在knockoutjs 上自己实现的flux(实例讲解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持编程之家。

    相关文章

    事件冒泡和事件捕获 起因:今天在封装一个bind函数的时候,发现el.addEventListener函数支持第三个参数...
    js小数运算会出现精度问题 js number类型 JS 数字类型只有number类型,number类型相当于其他强类型语言...
    什么是跨域 跨域 : 广义的跨域包含一下内容 : 1.资源跳转(链接跳转,重定向跳转,表单提交) 2.资源...
    @ "TOC" 常见对base64的认知(不完全正确) 首先对base64常见的认知,也是须知的必须有...
    搞懂:MVVM模式和Vue中的MVVM模式 MVVM MVVM : 的缩写,说都能直接说出来 :模型, :视图, :视图模...
    首先我们需要一个html代码的框架如下: 我们的目的是实现ul中的内容进行横向的一点一点滚动。ul中的内容...