
各位大神,请教如何解决此问题, 谢谢!
]]>同时又很孤独,想交流、学习,却没有地方。 meteorhub.org 几乎打不开,国内似乎也没有社区可以去上面学习的。后来自己草草弄了个网站 https://www.ameteor.com 。
真诚的希望有喜欢 Meteor 的朋友,可以一起做一下这个事情, 就是弄个高质量的 Meteor 社区网站,让更多喜欢 Meteor 的朋友可以聚在地一起学习、交流。
谢谢大家。
]]>简单来说, Mantra 是关于如何组织你的 Meteor 应用代码的标准,特别是前端部分 (基于 React),当然它对后端代码的组织也有要求。
如果你熟悉 React , Mantra 类似于 Flux ,讲究的是对数据流的控制,但是规定得更加细致。
Mantra 的目的是让程序写出更易于理解和维护的代码。它对几乎所有的情况都有一个标准,另外还为 Meteor App 增加单元测试覆盖率。
和 Perl 类似, Javascript 的一个难点就是同样一个问题有太多实现方式,而且可能都是最佳解决方案。所以经常是不同的人使用不同的方法。 Mantra 让 Meteor App 有一个统一的结构,遵循相同的标准,就像设计模式一样,降低大家理解代码结构的难度,确保模块之间解耦,像 Flux 一样让数据单向流动,这样维护代码更加容易。
Mantra 使用的原则很有前瞻性,能够很长时间不会过时,同时也允许其他人做必要的改变。
现在的 Web App 的大部分代码都是在前端。后端的代码逻辑相对简单也好管理,后端的难点在于性能优化,特别是大并发的处理,数据库等。
Mantra 的核心在如何组织客户端代码。它倡导前后端代码分离,前端不用知道后端代码是如何实现的,但是可以代码共享。因为是基于 React 又侧重前端,所以 Mantra 很类似 React 的那些标准,例如 Flux , Redux 等,解决的问题也类似,都是控制数据流 data flow ,让代码更易理解维护。如果你对 React 熟悉,理解 Mantra 就不难。如果理解有困难,建议多看看 React 的高级用法,例如 stateless/pure function , Higher Order Components 等。
Mantra 不相信 Universal App ,就是不相信一套前端代码适应所有终端平台。它鼓励一套后端代码,但是为每个前端平台开发单独的 app 来提高用户体验,尽量通过模块化来共享代码。
其他 Mantra 的基本介绍可以参看这篇中文翻译 http://www.jianshu.com/p/96d6b8e64c3a
下面我来详细解释 Mantra 的各个部件。
这里介绍的顺序和文档里的不一样,主要是先从新的概念介绍,不然对已经熟悉的也难理解。
应用上下文 context 对所有 action 和 container 开放读取,所以这是你分享变量的地方。
import * as Collections from '/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 可以让大家少写重复的代码,又可以在不同模块之间分享变量。
处理业务逻辑的模块。包括验证,状态管理和远程数据交互。
Action 就是一个简单的函数而已,第一个参数必须是应用的上下文 Context 。 Action 不得使用引入除了参数以外的任何变量和模块,甚至全局变量,但是可以使用库函数。
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); } }; Mantra 只使用 React 作为 UI 组件。
在 UI 组件内部不需要知道 App 的其他任何内容,也不应该读取和修改应用的 state 。 UI 使用到的数据和事件应该由 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 只负责展示界面,没有逻辑、状态等处理。
有两种状态:本地状态(客户端)和远程状态(服务器)。本地状态不和外界发生联系;远程状态需要和外界,例如数据库同步数据。
类似 Flux 里的 store 概念 (可参考 使用 Meteor 和 React 开发 Web App ), Meteor 有不同的方式实现,例如 MiniMongo , ReactiveDict 等。 Mantra 在这方面很灵活,没有要求用哪一种。但是还是有一些规则
首先,什么是依赖? Mantra 有两种依赖
例如:
const cOntext= { DB, Router, appName: 'My Blog' }; const actiOns= { posts: { create({DB, Router}, title, content) { const id = String(Math.random()); DB.createPost(id, title, content); Router.go(`/post/${id}`); } } }; 然后注入依赖。 Mantra 使用 react-simple-di 这个包来进行依赖注入。背后其实就是 React context 。这个包接受 Context 和 Actions 作为依赖。
import {injectDeps} from 'react-simple-di'; import Layout from './layout.jsx'; // 上面定义的 context 和 actions 定义在这里 const LayoutWithDeps = injectDeps(context, actions)(Layout); 现在 LayoutWithDeps 就可以在 app 里随意使用了。
如何使用依赖?
首先创建一个 UI 组件。可以看到这个组件的依赖是通过 props 传入的
class CreatePost extends React.Component { render() { const {appName} = this.props; return ( <div> Create a blog post on app: ${appName}. <br/> <button OnClick={this.create.bind(this)}>Create Now</button> </div> ); } create() { const {createPost} = this.props; createPost('My Blog Title', 'Some Content'); } } 使用依赖
const {useDeps} from 'react-simple-di'; // 前面定义的 CreatePost react 组件 const depsToPropsMapper = (context, actions) => ({ appName: context.appName, createPost: actions.posts.create }); const CreatePostWithDeps = useDeps(depsToPropsMapper)(CreatePost); 如果你没有定义自己的 mapper 函数(就是上面的 depsToPropsMapper ), useDeps 将使用下面的默认 mapper 函数,这样就可以直接使用 context 和 actions 了。
const mapper = (context, actions) => ({ context: () => context, actions: () => actions }); Mantra 使用依赖注入的目的是隔离代码。例如隔离 UI 组件和 actions 。
一旦配置好, Applicaton Context 就会被注入到把 Context 作为第一参数的 action 。
Container 同样也能读取 Application Context 。
不能在子组件里注入依赖,只能是最上层组件,通常就是 Layout Component ,例如下面代码。
import React from 'react'; export default function (injectDeps) { // See: Injecting Deps const MainLayoutCtx = injectDeps(MainLayout); // Routes related code } Container 的作用是集成、组装数据。它的中文意思是容器,里面包裹的就是 UI 组件。主要功能:
Container 是一个 React 组件。如这篇文章所述的 Controller-View

如上图所示,使用一个父组件,就是 Mantra 的 container 来监听数据的变化,子组件 UI Component 负责界面渲染和互动。 Controller 就是高阶组件 (Higher Order Components) HOC 来包裹 UI 组件。高阶组件负责数据查询,子组件负责渲染等。
Mantra 使用 react ‐ komposer 来作为 container 获取数据状态。
container 的规则
]]>Note: 基于 Mantra Draft 0.2.0
https://www.livecoding.tv/johncarmack/videos/nDnyw-startup-with-meteor-for-a-social-web-app
项目还在开发中,大家可以去看他的直播或视频。
主要使用的编程语言: Javascript / HTML 5 / CSS3
使用的包,库和 API : Meteor.js and React.js
]]>一周前,我从网站开发的技术发展这一角度讲明 Meteor 旨在帮助我们编写出应运时代潮流的网站。今天,我试着转述 Meteor 创始人之一 Geoff Schmidt 眼中的计算终端发展简史。对比着看,也可以看出一个人看待事物的角度基本决定了他做事的格局。

Mainframe 是什么东西?大型主机。不过在这里它特指上世纪六七十年代的大型计算机,它体积庞大,计算处理能力远不及现今的 iPhone 手机。手机握于手掌, Mainframe 呢,一间教室都未必放得下一台。然而,它仍然意义深远,因为它具有计算处理能力,这是一切未来发展的根基。
PC 这个缩写大家肯定熟悉,个人计算机。它的意义在于体积的大幅缩小,以及成本的大幅降低。破坏性创新指将现有的需要较高消费能力才能享用的事物或服务通过创新方式重新打包为适用于普罗大众消费的商品的行为,重复即重要。几千美元,一张桌子,便可拥有一台计算效率远超人类的个人电脑。当时的现状是,工具出现了,但人们还不太清楚能利用它实现什么。
直至软件业发展起来。图形界面允许非专业人士与冷冰冰的电脑进行交互操作,从而帮助更多的人使用计算机实现他们的需求,没错,又一次破坏性创新。个人计算机的使用者具备了超人的计算能力,但是呢,数据交换还无法摆脱地理隔离,最多是用软盘携带着有限的数据往来于书房和办公室。
直至互联网的普及。全球经济、文化的发展速度依赖于低延迟的信息送达。从奔跑,到骑马;从电报,到互联网。不仅全球范围内信息送达几近为零延迟,而且能够承载越来越丰富的数据。从文本到视频,从即时聊天到网络直播,没有互联网基础设施的建设,相关的服务就不可能实现。
从这里,我的那篇网站发展简史就算是能接上了,我知道你懒得看,这里简单陈述一下大意。互联网让数据交换有了突破地理隔离的优势,结合拥有超高计算能力的服务器,网站开发更倾向于向访问者的浏览器传输计算后的结果—— HTML ;现如今,访问者的终端——包括个人计算机和手机——计算能力越来越强,有人开始考虑直接向访问者的浏览器传输数据,让浏览器获得数据后在本地进行计算和渲染,这一转变允许网站开发者开发出交互更复杂的网站,这一点我在上周已经举过例子了,包括开源项目和商业网站。
Meteor 的概念正是在这一大背景下提出的,同时 Meteor 团队也在这四年内做到了,并且未来还会朝着更开放的方向发展。从大型主机,到个人电脑;从互联网,到移动应用。终端的体积不断缩小,成本不断降低,处理能力不断提高,数据交换不再受地理隔离,这一切一切的基础条件预示着太多的可能性,直至相应的软件业再一次发展起来。
相互连接的移动设备是未来终端的绝对主力,它们愈加便携、便宜,这一趋势则会愈加凸现。 Meteor 现已能够全方位地支持这一趋势,并将持续进化以应对生态环境的突变。
欢迎订阅我的微信公众号:两个圆点一条直线 - /t/275760
]]>感兴趣的可以 RSS 订阅,也可以去微信搜索 两个圆点一条直线 订阅关注。
如果你以前关注过并放弃了 Meteor ,请告诉我你的疑虑,我可以根据其现状 (1.3 版本) 和已知的未来发展方向进行回答,让我们重新评估一下 Meteor 到底适不适合自己的新项目。
]]>最近有一个迫切的压力让我尽快学习 Meteor 结合 React (以及其他相关前端的技术),这对一个只会 jQuery ,对前端各种火热技术只是初步了解的人来说,真是比较大的挑战——包括思维上的改变和克服经验的不足。
于是白天继续打杂搬服务器,装电话线……晚上看资料,敲代码,幸好有领路人给了不少资料,大大减少了学习时间。
我发现网上分别讲 meteor 、 react 等的资料都挺多的,但貌似还没有找到一篇中文的,并且专门讲如何把这些技术结合起来的文章,所以写完代码就整理了一份文档,以帮助和我一样入门的 V 友。
已经使用到的技术清单
Meteor 基础开发框架(以及自带的 MongoDB , accounts-ui,check 等 packages)
Meteor-React 前端库
FlowRouter 客户端路由
react-layout 结合 FlowLayout 实现 react JSX 的布局
Semantic-UI 前端界面库
其他 Meteor 插件
地址:
https://github.com/my101du/meteor-react-flowrouter-semantic-singledog
完全是学习入门的潦草形态,没有考虑到代码的整洁和“最佳实践”(这个词我一直觉得莫名其妙),并且 bug 繁多,请高手指出我可以继续提高的方向和技巧。
]]>解决办法: https://github.com/englue/meteor-publish-composite 使用这个包可以解决服务器端的 join 逻辑复杂的问题
关于这方面一些相关的文章: https://www.discovermeteor.com/blog/reactive-joins-in-meteor/
解决办法
1.用 Template.<my object>.helpers 返回一个关联文档的指针 读取指针的值时会触发 Meteor 的重绘注册机制 所以当被关联的对象对象更新时就触发了重绘 例如
Template.book.helpers ({ 'author' : function (){ return Authors.find (this.authorId ); } }); 朋友推荐了 Meteor.js 我也稍微研究了一下 看似很美好 但是不知道实际开发的时候会不会遇到什么问题?
比如
- 后台自定义业务逻辑是否会很困难?
我以前也遇到过像 Django cakePHP 这样的框架 虽然功能很完善 可以重复利用的模块很多 但是有些模块自定义开发太复杂 甚至复杂到不如自己重新写的程度
- 是否遇到明显的效率问题?能否应对手机多变的网络环境?
Metero.js 里的 live query 虽然很好用 但是毕竟需要长时间保持连接 一个是如果是手机使用 数据流量会不会太大? 还有一个是这样大量的交换数据会不会导致电量消耗过快? 如果是移动网络这种经常掉线、不稳定的环境 有没有遇到什么奇怪的问题?
- 服务器的性能开销横向对比的结果如何?
因为需要维持大量客户端的 WebSocket 会不会导致服务器的内存和 CPU 的开销太大?
楼主正在严肃考虑要不要分配一点开发时间出来用 meteor.js 做一个快速原型 所以如果有 V 有在正式产品开发中用过 meteor.js 请不吝赐教 或者加我 qq 交流交流 523823374
]]>同学们可以在上面分享Meteor经验,或是使用Meteor过程中遇到了困难,不用怕,可以到社区寻求帮助
]]>后来一直想用meteor重新写一遍,一直在拖延,结果这次赶在 MeteorDay 之前终于是做出来了。
但是由于网络延迟和算法不够好,目前的实际的效果还很差。之后会看看 profile 专攻一下性能优化。
如果打不开可能是因为 Google web Fonts 被墙没加载出来,点击一下esc就好。
按照惯例继续 公开代码
]]>meteor.js 离 1.0 越来越近了,11月6号全球各地都会举行的活动,和 hangout 。
之前的 0.9 版本提供了官方的包管理机制,1.0 将很可能拥有下面 roadmap 里承诺的功能。
我会去北京的活动,组织者还在找场地。按已往的经验看参与人数应该不会超过50人,希望大家能有推荐。
]]>