来看看Meteor的功能
看了一上午,感觉这确实比所谓传统的APP开发,有很多不一样的地方。
记录下来:
simple-todos.css
/* CSS declarations go here */ /* CSS declarations go here */ body { font-family: sans-serif; background-color: #315481; background-image: linear-gradient(to bottom, #315481, #918e82 100%); background-attachment: fixed; position: absolute; top:; bottom:; left:; right:; padding:; margin:; font-size: 14px; } .container { max-width: 600px; margin: 0 auto; min-height: 100%; background: white; } header { background: #d2edf4; background-image: linear-gradient(to bottom, #d0edf5, #e1e5f0 100%); padding: 20px 15px 15px 15px; position: relative; } #login-buttons { display: block; } h1 { font-size: 1.5em; margin:; margin-bottom: 10px; display: inline-block; margin-right: 1em; } form { margin-top: 10px; margin-bottom: -10px; position: relative; } .new-task input { box-sizing: border-box; padding: 10px 0; background: transparent; border: none; width: 100%; padding-right: 80px; font-size: 1em; } .new-task input:focus{ outline:; } ul { margin:; padding:; background: white; } .delete { float: right; font-weight: bold; background: none; font-size: 1em; border: none; position: relative; } li { position: relative; list-style: none; padding: 15px; border-bottom: #eee solid 1px; } li .text { margin-left: 10px; } li.checked { color: #888; } li.checked .text { text-decoration: line-through; } li.private { background: #eee; border-color: #ddd; } header .hide-completed { float: right; } .toggle-private { margin-left: 5px; } @media (max-width: 600px) { li { padding: 12px 15px; } .search { width: 150px; clear: both; } .new-task input { padding-bottom: 5px; } }
simple-todos.html
<head> <title>Todo List</title> </head> <body> <div class="container"> <header> <h1>Todo List({{incompleteCount}})</h1> <lable class="hide-completed"> <input type="checkbox" checked="{{hideCompleted}}" /> Hide Completed Tasks </lable> {{> loginButtons}} {{#if currentUser}} <form class="new-task"> <input type="text" name="text" placeholder="Type to add new tasks" /> </form> {{/if}} </header> <ul> {{#each tasks}} {{> task}} {{/each}} </ul> </div> </body> <template name="task"> <li class="{{#if checked}}checked{{/if}} {{#if private}}private{{/if}}"> <button class="delete">×</button> <input type="checkbox" checked="{{checked}}" class="toggle-checked" /> {{#if isOwner}} <button class="toggle-private"> {{#if private}} Private {{else}} Public {{/if}} </button> {{/if}} <span class="text"><strong>{{username}}</strong> - {{text}}</span> </li> </template>
simple-todos.js
Tasks = new Mongo.Collection("tasks"); if (Meteor.isServer) { Meteor.publish("tasks", function() { return Tasks.find( { $or: [ { private: {$ne: true }}, { owner: this.userId } ] }); }); } if (Meteor.isClient) { Meteor.subscribe("tasks"); Template.body.helpers({ tasks: function(){ if (Session.get("hideCompleted")) { return Tasks.find({checked: {$ne: true}}, {sort: {createdAt: -1}}); }else{ return Tasks.find({}, {sort: {createdAt: -1}}); } }, hideCompleted: function(){ return Session.get("hideCompleted"); }, incompleteCount: function(){ return Tasks.find({checked: {$ne: true}}).count(); } }); Template.body.events({ "submit .new-task": function (event) { event.preventDefault(); var text = event.target.text.value; Meteor.call("addTask", text); event.target.text.value = ""; }, "change .hide-completed input": function(event){ Session.set("hideCompleted", event.target.checked); } }); Template.task.helpers({ isOwner: function() { return this.owner === Meteor.userId(); } }); Template.task.events({ "click .toggle-checked": function(){ Meteor.call("setChecked", this._id, ! this.checked); }, "click .delete": function(){ Meteor.call("deleteTask", this._id); }, "click .toggle-private": function() { Meteor.call("setPrivate", this._id, ! this.private); } }); Accounts.ui.config({ passwordSignupFields: "USERNAME_ONLY" }); } Meteor.methods({ addTask: function(text) { if (! Meteor.userId()) { throw new Methor.Error("not-authorized"); } Tasks.insert({ text: text, createdAt: new Date(), owner: Meteor.userId(), username: Meteor.user().username }); }, deleteTask: function(taskId) { var task = Tasks.findOne(taskId); if (task.private && task.owner !== Meteor.userId()) { throw new Meteor.Error("not-authorized"); } Tasks.remove(taskId); }, setChecked: function(taskId, setChecked) { var task = Tasks.findOne(taskId); if (task.private && task.owner !== Meteor.userId()) { throw new Meteor.Error("not-authorized"); } Tasks.update(taskId, {$set: { checked: setChecked} }); }, setPrivate: function(taskId, setToPrivate) { var task = Tasks.findOne(taskId); if (task.owner !== Meteor.userId()) { throw new Meteor.Error("not-authorized"); } Tasks.update(taskId, { $set: { private: setToPrivate } }); } });
截图:
来看看Meteor的功能的更多相关文章
- JavaScript 开发者的 10 款必备工具
JavaScript,一种所有主流浏览器都支持的语言,是开发基于浏览器的 Web 应用程序的主力,几乎每年都会受到来自众多开发人员的关注.自然地,框架和库的生态系统自然而然地围绕着 JavaScrip ...
- Meteor+AngularJS:超快速Web开发
为了更好地描述Meteor和AngularJS为什么值得一谈,我先从个人角度来回顾一下这三年来WEB开发的变化: 三年前,我已经开始尝试前后端分离,后端使用php的轻量业务逻辑框架.但 ...
- Meteor全栈开发平台 - 不仅仅是前端
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,博客地址为http://www.cnblogs.com/jasonnode/ .网站上有对应每一 ...
- 怎么评价Facebook的Relay框架?Meteor.js 是什么?
http://www.zhihu.com/question/34531232?rf=34500201 Meteor.js 是什么? 作者:陈天链接:http://www.zhihu.com/quest ...
- Meteor 之 数据的发布于订阅(Publish and subscribe )
发布和订阅 发布(Publication)和订阅(Subscription)是 Meteor 的最基本最重要的概念之一,但是如果你是刚刚开始接触 Meteor 的话,也是有些难度的. 这已经导致不少误 ...
- Meteor 简介
简介 先来活动一下大脑.假设你坐在电脑面前,在两个窗口中打开同一个文件夹. 在其中一个窗口中删除一个文件,另一个窗口中的这个文件会消失吗? 不用实际操作你也知道肯定会消失的.在本地文件系统中的操作,不 ...
- Meteor:用户账号管理添加密码和微博weibo账号系统支持
Meteor账户系统构建与accounts-base包之上,并为publish和methods提供userId的顶层支持.核心包提供的功能有:数据库中的用户记录支持:额外的包提供密码安全验证:第三方登 ...
- Meteor全栈开发平台
Meteor全栈开发平台 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,博客地址为http://www.cnblogs.com/jasonno ...
- javascript功能插件大集合,写前端的亲们记得收藏
伯乐在线已在 GitHub 上发起「JavaScript 资源大全中文版」的整理.欢迎扩散.欢迎加入. https://github.com/jobbole/awesome-javascript-cn ...
随机推荐
- js动态生成按钮,页面用DIV简单布局2
对前边不完善的修改 <!DOCTYPE html><html><head><title>test.html</title> <meta ...
- css关于宽度
很多时候,我们指定了某个元素的宽度,浏览器渲染时却只给这个元素一半的宽度,这时可以试试min-width属性,该属性表示浏览器不能偷懒,资源再紧张也得分配min-width指定的宽度.
- C# String 前面不足位数补零的方法 PadLeft
PadLeft(int totalWidth, char paddingChar) //在字符串左边用 paddingChar 补足 totalWidth 长度PadLeft(int totalWid ...
- Android通过tcpdump抓包(wifi, 2g, 3g都可以)
http://blog.csdn.net/deng529828/article/details/20646197 1. 手机要有root权限 2. 下载tcpdump http://www.str ...
- 日志记录类LogHelper
开源日志log4net使用起来很方便,但是项目中不让用,所以自己重写了一个类,用来记录日志,比较简单. 1.首先是可以把日志分成多个类型,分别记录到不同的文件中 /// <summary> ...
- Xcode中,调试console窗口输出error: Couldn't materialize struct: the variable 'cell' has no location, it may have been optimized out的问题
Xcode中调试代码时,常常需要使用console窗口查看变量的信息,比如使用了如下的命令来输出有关UITableView中一个UITableViewCell的信息, po cell 令人感到意外的是 ...
- 14_Request对象
[HttpServletRequest简介] HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过 ...
- vs 2010 Cannot find or open the PDB file
打开VS2010:工具-->选项-->>调试-->符号接下来就是选择Microsoft,然后确认 接着随便编译一个程序,过程会灰常的慢. 看到此目录下符号缓存了吗?C:\Us ...
- HDOJ 1176 免费馅饼 -- 动态规划
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1176 Problem Description 都说天上不会掉馅饼,但有一天gameboy正走在回家的小 ...
- 九度OJ 1510 替换空格
题目地址:http://ac.jobdu.com/problem.php?pid=1510 题目描述: 请实现一个函数,将一个字符串中的空格替换成"%20".例如,当字符串为We ...