欢迎加入QQ讨论群258996829
麦子学院 头像
苹果6袋
6
麦子学院

细说Meteor Mantra的基本概念

发布时间:2016-08-18 23:31  回复:0  查看:2722   最后回复:2016-08-18 23:31  

这是一篇关于MantraMeteor教程Mantra是一种基于 Meteor 1.3+React和 ES2015的 Meteor应用架构,主要作用让 Meteor应用代码架构标准化,特别是前端部分,当然它对后端代码的组织也有要求。注意 Mantra 不是一个框架,而是一套如何构建Meteor App 的说明,同时也有配套的开源库来提高代码编写效率。

如果你熟悉 ReactMantra 类似于 Flux,讲究的是对数据流的控制,但是规定得更加细致。

目的

Mantra 的目的是写出更易于理解和维护的代码。它对几乎所有的情况都有一个标准,另外还为Meteor App 增加单元测试覆盖率。

和 Perl类似,JavaScript的一个难点就是同样一个问题有太多实现方式,而且可能都是最佳解决方案。所以经常是不同的人使用不同的方法。Mantra Meteor App 有一个统一的结构,遵循相同的标准,就像设计模式一样,降低大家理解代码结构的难度,确保模块之间解耦,像Flux 一样让数据单向流动,这样维护代码更加容易。

Mantra 使用的原则很有前瞻性,能够很长时间不会过时,同时也允许其他人做必要的改变。

偏重前端

现在的 Web App 的大部分代码都是在前端。后端的代码逻辑相对简单也好管理,后端的难点在于性能优化,特别是大并发的处理,数据库等。

Mantra 的核心在如何组织客户端代码。它倡导前后端代码分离,前端不用知道后端代码是如何实现的,但是可以代码共享。因为是基于React 又侧重前端,所以Mantra 很类似React 的那些标准,例如FluxRedux 等,解决的问题也类似,都是控制数据流data flow,让代码更易理解维护。如果你对React 熟悉,理解Mantra 就不难。如果理解有困难,建议多看看React 的高级用法,例如stateless/pure functionHigher Order Components 等。

Mantra 不相信Universal App,就是不相信一套前端代码适应所有终端平台。它鼓励一套后端代码,但是为每个前端平台开发单独的app 来提高用户体验,尽量通过模块化来共享代码。

 

其他 Mantra的基本介绍可以参看这篇中文翻译 http://www.jianshu.com/p/96d6b8e64c3a

下面我来详细解释 Mantra的各个部件。

 

这里介绍的顺序和文档里的不一样,主要是先从新的概念介绍。下图是一个典型的Mantra App work flow


细说Meteor Mantra的基本概念

mantra_flow.png

Application Context

应用上下文 context对所有 action和 container开放读取,所以这是你分享变量的地方。

import *as Collectionsfrom '/lib/collections';import {Meteor}from 'meteor/meteor';import {FlowRouter}from 'meteor/kadira:flow-router';import {ReactiveDict} from 'meteor/reactive-dict';import {Tracker} from 'meteor/tracker';

export default function () {

  return {

    Meteor,

    FlowRouter,

    Collections,

    LocalState:new ReactiveDict(),

    Tracker

  };

}

从上面例子中可以看出,context可以让大家少写重复的代码,又可以在不同模块之间分享变量。

Actions

处理业务逻辑的模块。包括验证,状态管理和远程数据交互。

Action 就是一个简单的函数而已,第一个参数必须是应用的上下文ContextAction 不得使用引入除了参数以外的任何变量和模块,甚至全局变量,但是可以使用库函数。

export default {

  create({Meteor, LocalState, FlowRouter}, title, content) {

    if (!title || !content) {

      return LocalState.set('SAVING_ERROR','Title & Content are required!');

    }

 

    LocalState.set('SAVING_ERROR',null);

 

    const id = Meteor.uuid();

    // There is a method stub for this in the config/method_stubs

    // That's how we are doing latency compensation

    Meteor.call('posts.create', id, title, content, (err) => {

      if (err) {

        return LocalState.set('SAVING_ERROR', err.message);

      }

    });

    FlowRouter.go(`/post/${id}`);

  },

  clearErrors({LocalState}) {

    return LocalState.set('SAVING_ERROR',null);

  }

};

UI

Mantra 只使用React 作为UI 组件。

在 UI组件内部不需要知道 App的其他任何内容,也不应该读取和修改应用的 stateUI 使用到的数据和事件应该由 props从 container传入,或者通过事件作为 action props 传入。如果 UI组件使用到本地 state,那么这个 state不应该被外部的任何组件使用,仅限于组件内部使用。

Mantra 文档里给出的代码示例:

import React from 'react';

 

const PostList = ({posts}) => (

  <div className='postlist'> 

    <ul> 

      {posts.map(post => (

        <li key={post._id}> 

          <a href={`/post/${post._id}`}>{post.title}</a> 

       </li> ))}

    </ul> 

  </div>

);

 

export default PostList;

上面的例子代码就是 React里的无状态纯函数实现,UI只负责展示界面,没有逻辑、状态等处理。

State 管理

有两种状态:本地状态(客户端)和远程状态(服务器)。本地状态不和外界发生联系;远程状态需要和外界,例如数据库同步数据。

类似 Flux里的 store概念 ,Meteor有不同的方式实现,例如 MiniMongoReactiveDict等。Mantra在这方面很灵活,没有要求用哪一种。但是还是有一些规则

. Action 里可以读写 state

. Container 里只能读 state

. UI 组件里既不能读也不能写 state,只能由props 传入

 


原文来自:简书/荆雷

您还未登录,请先登录

热门帖子

最新帖子