bigbang

bigbang 查看完整档案

填写现居城市  |  填写毕业院校  |  填写所在公司/组织填写个人主网站
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 该用户太懒什么也没留下

个人动态

bigbang 提出了问题 · 2016-04-28

react、flux、redux三者之间的关系是什么?

react、flux、redux三者之间的关系是什么?

关注 3 回答 1

bigbang 赞了文章 · 2016-04-28

我对 React Flux 架构的理解

React Flux架构简介

个人现阶段对Flux架构的理解,求拍砖求star!
原文链接:https://github.com/kuitos/kuitos.github.io/issues/27

React 简介请戳 这里

Flux是什么

Flux是Facebook用来构建客户端web应用的应用架构。它利用单向数据流的方式来组合react中的视图组件。它更像一个模式而不是一个正式的框架,开发者不需要太多的新代码就可以快速的上手Flux。

Flux的核心部分

1. dispatcher

事件调度中心,flux模型的中心枢纽,管理着Flux应用中的所有数据流。它本质上是Store的回调注册。每个Store注册它自己并提供一个回调函数。当Dispatcher响应Action时,通过已注册的回调函数,将Action提供的数据负载发送给应用中的所有Store。应用层级单例!!

2. store

负责封装应用的业务逻辑跟数据的交互。

  • Store中包含应用所有的数据

  • Store是应用中唯一的数据发生变更的地方

  • Store中没有赋值接口---所有数据变更都是由dispatcher发送到store,新的数据随着Store触发的change事件传回view。Store对外只暴露getter,不允许提供setter!!禁止在任何地方直接操作Store。

3. view

  • controller-view 可以理解成MVC模型中的controller,它一般由应用的顶层容器充当,负责从store中获取数据并将数据传递到子组件中。简单的应用一般只有一个controller-view,复杂应用中也可以有多个。controller-view是应用中唯一可以操作state的地方(setState())

  • view(UI组件) ui-component 职责单一只允许调用action触发事件,数据从由上层容器通过属性传递过来。

4. 其他

action creators 作为dispatcher的辅助函数,通常可以认为是Flux中的第四部分。ActionCreators是相对独立的,它作为语法上的辅助函数以action的形式使得dispatcher传递数据更为便利。

How Flux(Unidirectional Data Flow) Works

  1. view --> actionCreators

    // Nav.jsx
    export default class Nav extends React.Component {
    
      _handleClick(nav) {
        NavActionCreators.clickNav(nav);
      }
    
      render() {
    
        let itemList = this.props.list.map((nav, index) => {
          return (
            <li className="index-menu-item" onClick={this._handleClick.bind(this, nav)} key={index}>
              <span>{nav.text}</span>
            </li>
          );
        });
    
        return (
          <nav className="index-menu">
            <ul className="index-menu-list">
              {itemList}
            </ul>
          </nav>
        );
      }
    }
  2. action dispatch

    // NavActionCreators.js
    export default {
    
      clickNav(nav){
    
        AppDispatcher.dispatch(
          {
            type: ActionTypes.CLICK_NAV,
            nav
          }
        );
      }
    };
  3. dispatcher --> store callback

    AppDispatcher.register(action => {
    
      switch (action.type) {
    
        // nav点击
        case ActionTypes.CLICK_NAV:
    
          IndexWebAPIUtils.getGiftList(_currentUserInfo.userId, action.nav.id)
            .then(function (giftList) {
    
              _currentGiftList = giftList;
              IndexStore.emitChange();
            });
    
          break;
    
        // no default
      }
    });
  4. store emitChange --> controller view --> setState

    export default class Index extends React.Component {
    
      constructor(props) {
        super(props);
        let currentUser = UserStore.getCurrentUser();
        this.state = IndexStore.getAll();
      }
    
      componentDidMount() {
        IndexStore.addChangeListener(this._onChange.bind(this));
      }
    
      componentWillUnmount() {
        IndexStore.removeChangeListener(this._onChange.bind(this))
      }
    
      _onChange() {
        this.setState(IndexStore.getAll());
      }
    
      render() {
    
        let state = this.state;
    
        return (
          <div className="page active">
            ...
            <Nav list={state.navList}/>
            ...
          </div>
        );
      }
    
    }

Flux vs MVVM

MVVM

1. 简单的MVVM

2. 复杂的MVC

Flux

1. 复杂的Flux

Flux的优势

1. 数据状态变得稳定同时行为可预测

因为angular双向绑定的原因,我们永远无法知道数据在哪一刻处于稳定状态,所以我们经常会在angular中看到通过setTimeout的方式处理一些问题(其实有更优雅的解决方案,不在本次讨论之内)。同时由于双向绑定的原因,行为的流向我们也很难预测,当视图的model变多的时候,如果再加上一堆子视图依赖这些model,问题发生时定位简直是噩梦啊(这也是angular的错误信息那么不友好的原因,因为框架开发者也无法确定当前行为是谁触发的啊,绑定的人太多了...)。但是这里还是要强调一点就是,并不是说双向绑定就一定会导致不稳定的数据状态,在angular中我们通过一些手段依然可以使得数据变得稳定,只是双向绑定(mvvm)相对于flux更容易引发数据不稳定的问题。

2. 所有的数据变更都发生在store里

flux里view是不允许直接修改store的,view能做的只是触发action,然后action通过dispatcher调度最后才会流到store。所有数据的更改都发生在store组件内部,store对外只提供get接口,set行为都发生在内部。store里包含所有相关的数据及业务逻辑。所有store相关数据处理逻辑都集中在一起,避免业务逻辑分散降低维护成本。

3. 数据的渲染是自上而下的

view所有的数据来源只应该是从属性中传递过来的,view的所有表现由上层控制视图(controller-view)的状态决定。我们可以把controller-view理解为容器组件,这个容器组件中包含若干细小的子组件,容器组件不同的状态对应不同的数据,子组件不能有自己的状态。也就是,数据由store传递到controller-view中之后,controller-view通过setState将数据通过属性的方式自上而下传递给各个子view。

4. view层变得很薄,真正的组件化

由于2、3两条原因,view自身需要做的事情就变得很少了。业务逻辑被store做了,状态变更被controller-view做了,view自己需要做的只是根据交互触发不同的action,仅此而已。这样带来的好处就是,整个view层变得很薄很纯粹,完全的只关注ui层的交互,各个view组件之前完全是松耦合的,大大提高了view组件的复用性。

5. dispatcher是单例的

对单个应用而言dispatcher是单例的,最主要的是dispatcher是数据的分发中心,所有的数据都需要流经dispatcher,dispatcher管理不同action于store之间的关系。因为所有数据都必须在dispatcher这里留下一笔,基于此我们可以做很多有趣的事情,各种debug工具、动作回滚、日志记录甚至权限拦截之类的都是可以的。

Flux的困境

1. 过多的样板代码

flux只是一个架构模式,并不是一个已实现好的框架,所以基于这个模式我们需要写很多样板代码,代码量duang的一下子上来了。。不过好在目前已经有很多好用的基于flux的第三方实现,目前最火的属redux。

2. dispatcher是单例

dispatcher作为flux中的事件分发中心,同时还要管理所有store中的事件。当应用中事件一多起来事件时序的管理变得复杂难以维护,没有一个统一的地方能清晰的表达出dispatcher管理了哪些store。

3. 异步处理到底写在哪里

  • 按flux流程,action中处理:依赖该action的组件被迫耦合进业务逻辑

  • 按store职责在store中处理:store状态变得不稳定,dispatcher的waitFor失效

4. 至今还没有官方实现

写在最后

  • 前端摩尔定律:前端每18个月难度增加一倍

  • 没有银弹

查看原文

赞 3 收藏 35 评论 2

bigbang 关注了问题 · 2016-04-28

解决如何学习reactjs的flux构架

看了ReactJS其实感觉还是比较轻松的。
但是感觉看Flux的时候,感觉好抽象,不知道怎么去学比较好。
还有可能就是对一些构建工具的不熟悉。再还就是S里面出现了很多import let这类的关键词,然后看着github上面下过来的一些案例。感觉这已经不是,我概念中的JS了。

如果要学好ReactJS+Flux(或Refulx、redux啥的),应该具备哪些知识点,学习路线应该是怎么样的?

还请高手指点一下,这两天比较困惑。

关注 6 回答 2

bigbang 赞了回答 · 2016-04-27

laravel的filter()方法的使用

第一,和你的问题无关,建议你修改下边这一行:

$articles = $request->user()->articles()->get(); // 改成下边
$articles = $request->user()->articles // 这是动态属性的调用方式,是常规用法

第二,来回答你的问题(你可能把问题想复杂了,其实像下边这样简单):

$published = $articles->filter(function ($article) {
    return $article->status == 1 && $article->publishing_time < Carbon::now();;
});

关注 2 回答 1

bigbang 提出了问题 · 2016-04-27

laravel的filter()方法的使用

下面的方法是取出一个用户的所有文章,再把文章分成两组,publishedunpublished,

public function index(Request $request)
{
    $articles = $request->user()->articles()->get();

    $published = $articles->filter(function ($article) {
        return $article->status == 1;
    });

    $unpublished = $article->filter(function ($article) {
        return $article->status == 0;
    });

    return view('user.dashboard.index', compact('published', 'unpublished'));
}

现在,在分组的时候,需要多增加一个过滤条件,比如这个:

$published = $articles->filter(function ($article) {
        return $article->status == 1;
    });

上面的过滤的条件只有1个,就是status == 1,
现在增加一个过滤条件publishing_time < Carbon::now();
那么,增加过滤条件后,语法怎么写呢?

关注 2 回答 1

bigbang 关注了问题 · 2016-04-27

求助,关于图片裁剪的问题!!!!!!

现在项目有一个需求,在一张背景底图上的中心区域的线框之内,放置一些图片和文字素材,超出部分会被overflow:hidden,然后我用的html2canvas.js插件,正常是没有问题,但是如果里面的素材经过transform: rotate后,裁剪的会出现bug,表现为,旋转似乎未生效一样, 希望大家帮我分析下怎么解决这个问题,或者有其他插件能够避免这个问题,先跪谢了!
下面是正常裁剪的,没问题
图片描述

然后下面经过旋转的

图片描述

裁剪后就成这样了

图片描述

关注 8 回答 4

bigbang 提出了问题 · 2016-04-27

启动phpstorm的时候说jvm路径无效

启动phpstorm的时候说jvm路径无效,弹出一个这样的框:
图片描述

打开路径,是这样的:
图片描述
环境变量是这样的:
图片描述
那么,是怎么回事呢?

关注 4 回答 3

bigbang 赞了回答 · 2016-04-27

解决laravel 什么地方需要Facade,ServiceProvider

  1. Laravel框架的其中一条核心思想是让开发者愉快的开发,所以它的接口做的非常友好,Facade只是一个捷径而已,所有的Facade接口都可以通过依赖注入的方式获取,完全根据开发者的喜好来选择,所以没有什么场景适合用Facade这一说

  2. Laravel框架的另一条思想是同一件事情,可以有多种做法,举例如下:

/** 调用Request服务 */
public function (\Illuminate\Http\Request $request) {
    /** 三种方式等价 */
    $inputs = $request->all(); // 依赖注入(DI)
    $inputs = \Request::all(); // Facade
    $inputs= = request()->all(); // 助手方法(helper method)
}

至于服务提供器Service Provider什么时候使用,简单解释如下:

  1. 如果你的服务(Services)不依赖于其他服务,则不需要服务提供器(Service Provider),你只需通过依赖注入该服务,Laravel的IoC容器会通过PHP的反射服务来实例化该服务。

  2. 反而,如果你的服务需要注入其他依赖服务,或者你的服务需要在使用前进行一些初始化的操作(bootstrap),那么这个时候,你就需要在服务提供器(Service Provider)的register方法内将服务绑定到Laravel的IoC容器内,进而在boot方法内,进行初始化操作(bootstrap),这个时候,程序所有的服务都已注册完毕,所以初始化的过程中,还可以调用其他服务。

关注 9 回答 2

bigbang 关注了问题 · 2016-04-27

解决laravel 什么地方需要Facade,ServiceProvider

关于laravel有很多很棒设计,我一直不太明白,Facade和ServiceProvider的应用场景
我一般建立一个Services目录,里面写上UsersService,ArticleService,
然后在controller中,直接进行依赖注入,即可实现了UsersService的操作

希望大神能讲解下,什么样的场景下适用Facade和ServiceProvider

关注 9 回答 2

bigbang 提出了问题 · 2016-04-27

laravel输出变量到模板,变量在模板中再分一次类可以吗?这样可以只查询一次数据库

laravel输出变量到模板,变量在模板中再分一次类可以吗?这样可以只查询一次数据库。
比如:
下面是一个用户的后台首页控制器,返回该用户发表的所有文章,像这样:

    public function index()
    {
        $user=\Auth::user();
        $articles = $user->articles;
        
        return view('user.dashboard.index',  compact('articles'));
    }

下面的代码是在view中显示所有文章:

<div class="card">
    <div class="card-header">
        所有文章
    </div>
    @if ($articles!=null)
    <table class="table table-sm">
        <thead>
        <tr>
            <th>标题</th>
            <th>发布时间</th>
            <th>发布状态</th>
            <th>操作</th>
        </tr>
        </thead>
        <tbody>
        @foreach ($articles as $article)
        <tr>
            <td>{{$article->title}}</td>
            <td>{{$article->created_at}}</td>
            <td>{{$article->status}}</td>
            <td>
                <a class="btn btn-primary btn-sm" href="#" role="button"><i class="fa fa-eye"></i>详情</a>
                <a class="btn btn-primary btn-sm" href="#" role="button"><i class="fa fa-edit"></i>编辑</a>
            </td>
        </tr>
        @endforeach
        </tbody>
    </table>
    @else
    <p>没有文章</p>
    @endif
</div>

可是,这些文章分为两类:
一类是“已发布”,数据库字段status,值为“1”,
一类是“未发布”,数据库字段status,值为“0”,

问题:
现在需要这两类文章分开显示,已发布的显示在一个card中,未发布的显示在一个card中,可以在模板中直接分类吗?这样的话就不用查两次数据库。

关注 5 回答 3

认证与成就

  • 获得 13 次点赞
  • 获得 85 枚徽章 获得 5 枚金徽章, 获得 31 枚银徽章, 获得 49 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2016-03-16
个人主页被 284 人浏览