美文网首页我爱编程
阮一峰FluxDemo学习

阮一峰FluxDemo学习

作者: 阿拉斌 | 来源:发表于2018-04-14 00:03 被阅读0次

    FluxDemo学习

    1. 基本概念

    首先,Flux将一个应用分为了四个部门

    • View: 试图层

    • Action:方法层,里面有各种方法

    • Dispatcher:分发器,里面放了很多Actions,然后可以执行他们

    • Store:数据层,要不叫持久层?通过这个来保存应用的各种状态,然后他变化了,View也会发生变化

      单向数据流———流程图:


      下面的流程图
    graph LR;
    
    Action-->Dispatcher;
    Dispatcher-->Store;
    Store-->View;
    View-->Action
    
    

    这就感觉像是一个圈,但是一般来说,是这样的

    当用户点击一个View上的一个按钮的时候,会发出一个Action

    然后Dispatcher会收到这个Action,然后叫Store去把数据更新了

    Store更新了之后呢,就会叫View把页面也更新了

    差不多就是这么个流程了。。。
    [图片上传中...(image.png-58a622-1523635613909-0)]

    2. 查看Demo

    然后我们去看下demo项目

    好吧,看到后缀是jsx我就懵了,jsx又是什么格式呢~,这个下次再讨论

    var React = require('react');
    var ReactDOM = require('react-dom');
    var MyButtonController = require('./components/MyButtonController');
    
    ReactDOM.render(
      <MyButtonController/>,
      document.querySelector('#example')
    );
    
    

    这个按钮组件的名字我们可以看出,我的 按钮 控制器

    这里采用的是React的controller view模式,只是用来进行状态的保存用的

    MyButtonController组件呢,主要通过他来对各种事件进行调用。

    我们可以看到,在这个组件里面,他有好几个function,在前面还有componentDidMount(组件初始化后执行一次),componentWillUnmount(移除的时候执行一次),在componentDidMount下面给ListStor中的addChangeListener传递进去了一个回调函数,也就是对ListStore进行操作的函数

      ...
      componentDidMount: function() {
        ListStore.addChangeListener(this._onChange);
      },
      
      ...
    
      createNewItem: function (event) {
        ButtonActions.addNewItem('new item');
      },
    
      render: function() {
        return <MyButton
          items={this.state.items}
          onClick={this.createNewItem}
        />;
    

    下面则一个MyButton组件,一共传递两个参数,一个是items(项目),一个的点击后的回调函数。

    var React = require('react');
    
    var MyButton = function(props) {
      var items = props.items;
      var itemHtml = items.map(function (listItem, i) {
        return <li key={i}>{listItem}</li>;
      });
    
      return <div>
        <ul>{itemHtml}</ul>
        <button onClick={props.onClick}>New Item</button>
      </div>;
    };
    
    module.exports = MyButton;
    

    这里可以看出,MyButton组件相当于一个纯组件,或者叫做一个“展示型”组件

    React可以分为两种,一种是容器型组件,一种是展示型组件,要区分他们的话,主要是看是否有数据操作。比如说上面的MyButtonController组件,他就是一个容器型组件,它于Store进行了操作。

    像上面的MyButton组件,他就执行了几个简单的操作,一个是你给我数据,我给你渲染出ul,一个是点击我时候,会触发你传递过来的createNewItem函数,用来调用Action中的addNewItem方法

      createNewItem: function (event) {
        ButtonActions.addNewItem('new item');
      },
    

    addNewItem则会告诉Dispatcher中的分发器去分发这个Action

      addNewItem: function (text) {
        AppDispatcher.dispatch({
          actionType: 'ADD_NEW_ITEM',
          text: text
        });
      },
    

    而在Dispatcher中呢,则会相应的对数据进行更新:

      switch(action.actionType) {
        case 'ADD_NEW_ITEM':
          ListStore.addNewItemHandler(action.text);
          ListStore.emitChange();
          break;
        default:
          // no op
      }
    

    3. Action

    每一个Action都是一个对象,包含一个actionTyp属性(说明动作的类型)和一些其他属性(用来传递数据)。---阮一峰

    4. Dispatcher

    Dispatcher的作用就是把Action派发到Store中去,是一个单例,它就负责联系View和Store。告诉他们两个Action应该怎么扔。

    我们在使用的时候,会需要引入一个AppDispatcher.js,然后new一个实例

    var Dispatcher = require('flux').Dispatcher;
    var AppDispatcher = new Dispatcher();
    

    并且在Dispatcher中,只能用来进行派发Action,不应该有其他的操作。

    5. Store

    Store其实就是MVC中的Model里面有各种get啊set啊之类的操作。
    在这个demo中,有一个ListStore来进行数据的存储。

      getAll: function () {
        return this.items;
      },
    
      addNewItemHandler: function (text) {
        this.items.push(text);
      },
    
      emitChange: function () {
        this.emit('change');
      },
    
      addChangeListener: function(callback) {
        this.on('change', callback);
      },
    
      removeChangeListener: function(callback) {
        this.removeListener('change', callback);
      }
    
    方法名 作用
    ListStore.items 保存数据,也就是保存里面的条目
    ListStore.getAll 获取所有的数据条目
    ListStore.addNewItemHandler 新增一个新的条目
    ListStore.emitChange 发射一个“change”事件
    ListStore.addChangeListener 添加改变监听
    ListStore.removeChangeListener 添加移除监听

    在上面的代码中,ListStore继承了EventEmitter.prototype,所以就可以使用ListStore.on()和ListStore.emit()来监听和触发事件了。

    Store更新后,会发出一个change事件,说明状态改变了,View监听后,查询新的状态,并更新页面

    6. View

    那么关于View呢,在MyButtonController组件中,它是可以监听change事件的。
    在组件创建的时候,会触发一个addChangeListener来进行change事件的监听,之后,在组件移除的时候,也会触发removeChangeListener事件。。。

    7.总结

    看了他这种写法,感觉Action,Service,Dao ~~~

    真的好像啊,Action里面有着各种各样的方法,当用户点击按钮的时候,触发Action事件,当然,这个Action是通过Controller来进行触发的,也就是容器组件。

    触发后,Action调用AppDispatcher中的分发器,来进行事件的具体实现,也就是相当于Service层

    service层的作用:

    1. 封装通用的业务逻辑,操作。
      如一些数据的检验,可以通用处理。
    2. 与数据层的交互。
    3. 其他请求:如远程服务获取数据,如第三方api等。

    相对于MVC中的直接和数据交互,Flux中的Store则更像是一个缓存,看官方的流程图介绍,在与后端进行交互的时候,是在Action Creators进行控制的。。。

    感觉就像是,前端的Action,和后端的Action进行数据交互,然后,拿到数据后,前端把数据调用AppDispatcher来进行数据分发,用Store来进行数据操作,从而影响View。

    而后端Action接收数据后,交给Service层进行业务处理,之后给Dao层保存进行数据库。

    我看到关于API访问放在哪的讨论,这个先不管了,我们按照官方的图进行操作吧。

    别人的流程图:

    下面的流程图
    graph LR;
    
    Action-->Dispatcher;
    Dispatcher-->Store;
    Store-->WebApi;
    WebApi-->Store;
    Store-->View;
    View-->Action
    
    

    流程图来源
    https://segmentfault.com/q/1010000002867736

    相关文章

      网友评论

        本文标题:阮一峰FluxDemo学习

        本文链接:https://www.haomeiwen.com/subject/ohwhkftx.html