diff --git a/pages/hackpack-researchkit.md b/pages/hackpack-researchkit.md new file mode 100644 index 0000000..84489ca --- /dev/null +++ b/pages/hackpack-researchkit.md @@ -0,0 +1,112 @@ +# ResearchKit 教程 + +在本教程中,我们将使用 Swift 4 和 XCode 9+ 来解决 Apple 的 ResearchKit 和 Healthkit 的问题。所需要的功能包括创建一个同意书以从用户那里请求批准,分发带有不同类型问题的调查表单,以及 iOS 应用程序从 iPhone 的 Health 应用程序中收集数据的访问点。 + +-------------------------------------------------------------------------------- + +首先,让我们创建一个标准的 XCode 项目。我们想通过以下步骤将 ResearchKit 和 HealthKit 嵌入到我们的 iOS 应用程序中。 + +1. 请注册一个开发者帐户(用于 HealthKit 使用),大约需要5-10分钟。[https://developer.apple.com/programs/] 克隆此存储库并按照步骤进行操作!使用 [master] 获取完整的解决方案和 [starterkit] 来填写代码。 + +2. 我们要下载最新版本的 ResearchKit,并在终端中键入 + +``` +git clone -b stable [https://github.com/ResearchKit/ResearchKit.git](https://github.com/ResearchKit/ResearchKit) +``` +然后,进入带有 `.xcodeprj` 扩展名的文件,并通过运行 ResearchKit 框架来构建项目。 + +3. 将 **ResearchKit.xcodeproj** 拖到当前 iOS 项目中,如果需要,请复制项目。如果在拖入后看不到 ResearchKit 旁边有箭头,请等待加载,或关闭并重新打开项目。 + +![addresearch](https://cloud.githubusercontent.com/assets/6894456/21839806/9a6d44d8-d78e-11e6-8c07-640776371eb2.png) + +4. 找到项目的 **General** 设置,并找到 `+Embedded Binaries`。单击 “+” 按钮并添加 ResearchKit。 + +![embed](https://cloud.githubusercontent.com/assets/6894456/21839842/d9c05b98-d78e-11e6-9857-5e3a72ee917d.png) + +5. 要使用 HealthKit,请找到 **Capabilities** 设置,滑动到底部以打开 HealthKit 访问,它会自动添加到你的项目中。 + +![healthkit](https://cloud.githubusercontent.com/assets/6894456/21839857/f3322408-d78e-11e6-8f2c-910e4bee392a.png) + +6. 在你的 `info.plist` 中,右键单击以打开源代码,然后粘贴: + +```swift +NSHealthShareUsageDescription +Need to share healthkit information +NSHealthUpdateUsageDescription +Need healthkit to track steps +``` + +![infoplist](https://cloud.githubusercontent.com/assets/6894456/21839876/0c9ce586-d78f-11e6-855a-0b214b4c08a4.png) + +7. (可选)如果你在 XCode 模拟器中测试代码,则必须从 Health App 模拟数据,以便从 HealthStore 获取结果。为此,请运行 iPhone 模拟器,单击硬件选项卡的主页按钮,然后导航到 Health 应用程序。点击要查看的类别,然后使用 “+” 按钮添加数据。例如,如果你要获取步数,那么请找到 **活动**,添加不同天数的运动量。 + +上面的步骤为你的 Xcode 项目安装了 ResearchKit 和 HealthKit。 + +-------------------------------------------------------------------------------- + +**master** 分支包含具有 ResearchKit 同意和调查表单以及 HealthKit 访问和步数计数的完整代码。**starterkit** 分支包含具有注释和适用于项目各部分的自行添加/自定义的代码部分。 + +**Main.storyboard** 创建导航控制器,将按钮连接到同意、调查和步数计数的特定功能,用于描述用途的文本框以及用于 HealthKit 数据的单独视图控制器。将按钮和文本框对齐以适应每个 iPhone 产品的规格。 + +**FirstViewController.swift** 将同意和调查按钮链接到其特定功能,该功能呈现一个具有特定任务(例如 ConsentTask 和 SurveyTasks)的新 taskViewController。taskViewController 继承自 ORKTaskViewController,用来在操作完成后关闭 viewController。 + +**ConsentDocument.swift** 和 **ConsentTasks.swift** 创建了一个同意书,要求用户同意研究。**ConsentTasks.swift** 创建了一个 ORKOrderedTask 来逐步执行创建的文档。**ConsentDocument.swift** 使用特定问题创建了一个 ORKConsentDocument,用户可以同意,并在表单中包含签名部分。同意事项的示例如下: + +```Swift +let consentSectionTypes: [ORKConsentSectionType] = [ + .overview, + .dataGathering, + .privacy, + .dataUse, + .studySurvey, + .studyTasks, + .withdrawing +] +``` + +**SurveyTask.swift** 创建了一个供用户填写的简单调查表单。它也是一个 ORKOrderedTask,初始化了问题的格式和详细信息,以及一个用于逐步执行的摘要步骤。示例问题如下: + +```Swift +let nameAnswerFormat = ORKTextAnswerFormat(maximumLength: 20) +nameAnswerFormat.multipleLines = false +let nameQuestionStepTitle = "What is your name?" +let nameQuestionStep = ORKQuestionStep(identifier: "QuestionStep", title: nameQuestionStepTitle, answer: nameAnswerFormat) +steps += [nameQuestionStep] +``` + +**HealthKitViewController.swift** 请求 HealthKit 访问并获取用户过去七天的步数。请记住,HealthKit 访问表单将仅出现一次,因为用户只需要接受一次协议。请求信息授权的示例代码如下: + +```Swift +if HKHealthStore.isHealthDataAvailable() { + let stepsCount = NSSet(object: HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)) + let sharedObjects = NSSet(objects: HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.height),HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.bodyMass)) + + healthStore.requestAuthorization(toShare: sharedObjects as? Set, read: stepsCount as? Set, completion: { (success, err) in + self.getStepCount(sender: self) + }) + +} +``` +创建用于 HealthStor 执行的查询的示例代码如下: +```Swift +let predicate = HKQuery.predicateForSamples(withStart: dates, end: Date(), options: []) +let query = HKSampleQuery(sampleType: type!, predicate: predicate, limit: 0, sortDescriptors: nil) { + query, results, error in + var steps: Double = 0 + var allSteps = [Double]() + if let myResults = results { + for result in myResults as! [HKQuantitySample] { + print(myResults) + steps += result.quantity.doubleValue(for: HKUnit.count()) + allSteps.append(result.quantity.doubleValue(for: HKUnit.count())) + } + } + completion(steps, allSteps, error as NSError?) + +} + +// Executes query through healthstore +healthStore.execute(query) +``` + +一上就是如何使用 Swift 4 和 XCode 9 来解决 ResearchKit 和 HealthKit 问题的教程。你可以自定义这些项目,并保存信息以在 iOS 应用程序中的其他部分使用,以此来创建一个医疗保健应用。 \ No newline at end of file diff --git a/pages/hackpack-web-api.md b/pages/hackpack-web-api.md index e038cee..02b25d0 100644 --- a/pages/hackpack-web-api.md +++ b/pages/hackpack-web-api.md @@ -1,47 +1,36 @@ -# Web API教程 +# Web API 教程 -### 概述 +### 介绍 -本研讨会的目标是学习如何使用 Node、MongoDB 和 Express 构建 RESTful Web API。从这个研讨会中,你将了解什么是 Web API,深入了解 Web 的前端/后端结构,并为你的 We b应用程序构建自己的后端!你还将学到一些关于 JavaScript 以及你可以在其中执行的所有有趣的事情。 +本教程的目标是讲述如何学习和使用 Node、MongoDB 和 Express 构建 RESTful Web API。在本教程中,你将了解什么是 Web API,深入了解 Web 的前端和后端结构,并为你的 Web 应用程序构建自己的后端!你还将学到一些关于 JavaScript 的知识以及你可以做的所有有趣的事情。 -### 研讨会 - 入门 -要开始完整的研讨会,请确保安装了 Node JS。运行以下命令: +阅读本教程前,请确保你已经安装了 Node JS。运行以下命令: ``` npm install npm start ``` -然后服务器应该在 `localhost:3000` 上启动。 +服务器将会在 `localhost:3000` 上启动。 -该服务器使用 `mongodb-memory-server` 将MongoDB以内存形式运行为数据库,使用Express处理API端点。 +该服务器使用 `mongodb-memory-server` ,将 MongoDB 以内存形式运行为数据库并使用Express处理 API 端点。 -如果你想挑战一下,使用`skeleton`分支(`git fetch && git checkout skeleton`),你可以自己填写API端点的实现。 +如果你想挑战一下使用 `skeleton` 分支(`git fetch && git checkout skeleton`),你可以自己填写 API 端点的实现。 ### 什么是API? -API 代表应用程序编程接口。简而言之,API 是一种从你自己的程序访问在服务器上运行的数据和服务的方式。一个很好的公开可用的 API 的例子是 Dog API(确实叫这个)位于https://dog.ceo/dog-api/。你可以通过点击每个路由下列出的 “JSON” 按钮,访问有关 Dog 的各种有趣信息。试试看! +API 是应用程序编程接口。简而言之,API 是一种从你自己的程序访问在服务器上运行的数据和服务的方式。一个很好的公开可用的 API 的例子是 Dog API,它位于 https://dog.ceo/dog-api/ 。你可以通过点击每个路由下列出的 “JSON” 按钮,访问有关 Dog 的各种有趣信息。 -你会注意到你将被重定向到一个包含一些文本的网页,文本使用花括号‘{}’格式化。你看到的是一个以 JSON(JavaScript对象表示法)表示的 JavaScript 对象。JS 对象本质上是 Python 字典或 C++ 映射,它的功能是将键映射到值。实际上 JavaScript 中的几乎所有东西都是一个对象(另一则故事),所以这很重要。它之所以重要的另一个原因是 JSON 是在 Web 中传输数据的标准方式,所以例如当你在网站上注册账户时,发送到Web服务器的数据是 JSON 格式的。此外, MongoDB 将其信息存储在 JavaScript 对象中。 +你将被重定向到一个包含一些文本的网页,文本使用花括号‘{}’格式化。你看到的是一个以 JSON(JavaScript对象表示法)表示的 JavaScript 对象。JS 对象本质上是 Python 字典或 C++ 映射,它的功能是将键映射到值。实际上 JavaScript 中的几乎所有东西都是一个对象,所以这很重要。它之所以重要的另一个原因是 JSON 是在 Web 中传输数据的标准方式,所以例如当你在网站上注册账户时,发送到Web服务器的数据是 JSON 格式的。此外, MongoDB 将其信息存储在 JavaScript 对象中。 -酷的是你可以将这些 API 调用传递到你的 Web 程序中,以便从应用程序中访问返回的数据。这使我们能够集成来自我们自己代码中的公共 API(以及TreeHacks赞助商提供的私有API)的各种有趣信息。我们将在研讨会中演示如何使用 Dog API 做到这一点! +你可以将这些 API 调用传递到你的 Web 程序中,以便从应用程序中访问返回的数据。这使我们能够集成来自我们自己代码中的公共 API 的各种有趣信息。我们将在教程中演示如何使用 Dog API 做到这一点! -### 前端与后端,单手揭示互联网的魔法 +### 前端与后端 -有没有想过互联网是如何工作的?非常简单,当你访问一个网站时,你正在从某个服务器接收一堆 JavaScript、CSS 和 HTML 文件,然后由你的 Web 浏览器运行。在你的浏览器中运行的代码是前端,提供信息的服务器上运行的代码是后端。Web 开发包括编写在两端都运行的代码(全栈开发),人们专门从事其中一方。API本质上是从后端提供资源的代码。由于我们正在构建一个 Web API,我们的研讨会的重点将放在构建后端上。 +有没有想过互联网是如何工作的?非常简单,当你访问一个网站时,你会从某个服务器接收一堆 JavaScript、CSS 和 HTML 文件,然后由你的 Web 浏览器运行。在你的浏览器中运行的代码是前端,提供信息的服务器上运行的代码是后端。Web 开发包括编写在两端都运行的代码(全栈开发),人们专门从事其中一方。API 本质上是从后端提供资源的代码。由于我们正在构建一个 Web API,本教程的重点将放在构建后端上。 ### 为动物收容所构建社交网络 -在研讨会中,我们将假装构建一个 Web API,供一家假设的动物收容所使用。基本上,动物收容所希望能够随机将动物分配给新主人。由于他们位于硅谷,他们还希望在这个操作之上建立一个社交网络,以便能够查看哪些狗主人是朋友,以便协调狗主人的聚会。他们来到 TreeHacks 找一些聪明的大学生为他们完成这个任务,价格便宜。 - -为了完成这项任务,我们将使用 Node 和 Express 构建一个 Web API,该 API 与 Dog API 进行交互,以及一个相应的前端,允许动物收容所查看有关他们的用户的所有信息。我们希望支持添加人员和将庇护所的狗分配给他们的操作,查看所有狗主人,在两个狗主人之间添加朋友关系,显示狗主人的朋友以组织聚会,并从数据库中删除一个狗主人,以防其狗死亡...(我们想不出更好的理由了,抱歉,我知道这很黑暗,但知道如何做是很重要的,RIP)。 - -### 资源 - -你可以在这个 GitHub 仓库的 Master 分支下访问我们的 Web API 的全部代码,并查看我们演示中使用的幻灯片! - -Mozilla 还有一个名为 MDN 的出色文档网站,详细介绍了你可能想了解的有关 Web 开发的任何东西。他们有一个很好的文本指南,介绍了 Web 开发的入门知识:https://developer.mozilla.org/en-US/docs/Learn - -我们使用的幻灯片是由 TheNetNinja YouTube 频道的 REST API 教程播放列表慷慨提供的。他更深入地解释了构建 REST API 时正在发生的事情,同时使用 React 构建了一个很棒的应用程序,扩展了前端开发方面。你可以在这里查看:https://www.youtube.com/playlist?list=PL4cUxeGkcC9jBcybHMTIia56aV21o2cZ8 - +在本教程中,我们将构建一个 Web API,供一家的动物收容所使用。事实上,动物收容所希望能够随机将动物分配给新主人。由于他们位于硅谷,他们还希望在这个操作之上建立一个社交网络,以便能够查看哪些狗主人是朋友,以便协调狗主人的聚会。 +为了完成这项任务,我们将使用 Node 和 Express 构建一个 Web API,该 API 与 Dog API 进行交互,以及一个相应的前端,允许动物收容所查看有关他们的用户的所有信息。我们的 Web API 支持添加人员和将庇护所的狗分配给他们的操作,查看所有狗主人的社交网络,在两个狗主人之间添加朋友关系,显示狗主人的朋友以组织聚会,并从数据库中删除一个狗主人。 diff --git a/pages/hackpack-web-frontend.md b/pages/hackpack-web-frontend.md index 86338de..1bfbdb8 100644 --- a/pages/hackpack-web-frontend.md +++ b/pages/hackpack-web-frontend.md @@ -1,16 +1,16 @@ -# Web Frontend Hackpack +# Web Frontend 教程 -我们将构建一个类似于以下样式的日记/笔记网络应用: + 在本教程中,我们将会教你如何开发一个如下图所示日记网页程序 ![示例](https://cloud.githubusercontent.com/assets/3401801/21839837/cc082120-d78e-11e6-836e-0cad2e505736.png) -为了构建这个应用,我们将使用 React 和 Redux。为了存储我们的数据,我们将使用 LocalStorage,它允许您在浏览器中拥有一种小型数据存储。 +为了构建我们的网站,我们将使用 React 和 Redux。除此之外,由于我们希望下次打开网页还可以看到我们写过的日记,我们需要在本地储存数据,那么就要用 LocalStorage 去存储我们的数据,这是一种允许用户在浏览器中拥有一种小型数据存储的技术。 -有许多不同的方法和框架可以用来创建相同的应用,但我喜欢 React + Redux,因为它们共同为您提供了一种处理交互、流动数据和为应用创建新功能的非常清晰和逻辑的方式。 +我们有许多不同的方法和框架可以用来创建相同的应用,但我喜欢 React 和 Redux,因为它们为你提供了一种非常清晰和逻辑地去处理交互、流动数据和为应用创建新功能的方式。 -本教程包括使用许多 ES6(和JavaScript的更新版本)语法的代码。如果您对某些语法不熟悉,[这里](http://es6-features.org/)是一个很好的参考来源。如果您对JavaScript不熟悉,[这里](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference)是一个很好的参考工具,[这里](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/A_first_splash)和[这里](https://www.codecademy.com/)是很好的学习资源。 +本教程包括使用许多 ES6(和JavaScript的更新版本)语法的代码。如果你对某些语法不熟悉,[此教程](http://es6-features.org/)是一个很好的参考来源。如果你对JavaScript不熟悉,[此教程](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference)是一个很好的参考工具,[此教程](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/A_first_splash)和[此教程](https://www.codecademy.com/)是很好的学习资源。 -首先,确保您已经安装了git并克隆了此存储库: +首先,确保你已经安装了git并克隆了此存储库: ``` git clone https://github.com/TreeHacks/hackpack-web-frontend @@ -24,30 +24,27 @@ cd hackpack-web-frontend npm install ``` -这可能需要一些时间,但一旦安装完成,请确保你可以通过运行以下命令来启动应用程序: - - +这可能需要一些时间,安装完成后,请确保你可以通过运行以下命令来启动应用程序: ``` npm run dev ``` -这个命令运行一个开发服务器(你可以在 `package.json` 中查看实际的命令),它会在你进行更改时自动重新加载你的应用程序。在本教程中,你不需要太担心这个命令的具体内容(但如果你感兴趣的话,该应用程序正在使用 [React 热加载](https://www.youtube.com/watch?v=xsSnOQynTHs))。 - -打开 [http://localhost:3000](http://localhost:3000),你应该能看到一个相当空的界面。 +这个命令会运行一个开发服务器,它会在你进行更改时自动重新加载你的应用程序。在本教程中,我们不会提到这个命令的具体内容(但如果你感兴趣的话,该应用程序正在使用 [React 热加载](https://www.youtube.com/watch?v=xsSnOQynTHs))。 -现在你已经成功安装并运行了应用程序,让我们开始编码。 +打开 [http://localhost:3000](http://localhost:3000),你应该能看到一个空界面。 -在 React 中,你的应用程序的每个部分(按钮、标题等)都可以被定义为一个 '组件',你可以在需要的任何地方重复使用它们。 +现在你已经成功安装并运行了应用程序,让我们开始写代码吧。 +在 React 中,你的应用程序的每个部分(按钮、标题等)都可以被定义为一个 “组件“,你可以在需要的任何地方重复使用它们。 -Redux 本质上允许我们在应用程序中拥有一个集中的数据存储,我们可以通过应用程序流动数据并分派操作来修改它(如果现在完全不明白,不要担心!稍后你会明白的)。 +Redux 本质上允许我们在应用程序中拥有一个数据集中的数据存储,我们可以通过应用程序流动数据并分派操作来修改它(稍后我们会详细介绍)。 -### 构建块(组件) +### 构建组件 -对于日记界面,我们将需要一个侧边栏和一个编辑界面组件。侧边栏将列出您的条目,您可以单击其中一个来进行编辑,或者创建一个新的条目。编辑界面将是一个纯文本输入区域。让我们进一步定义这些组件。 +对于日记界面,我们将需要一个侧边栏和一个编辑界面组件。侧边栏将列出你的日记条目,你可以单击其中一个来进行编辑,或者创建一个新的日记条目。编辑界面将是一个纯文本输入区域。让我们进一步定义这些组件。 -在 `src/app/components/journal/Sidebar.jsx` 中,用以下内容替换: +将位于 `src/app/components/journal/Sidebar.jsx` 中的代码,用以下代码替换: ```jsx import React from 'react'; @@ -92,12 +89,12 @@ const Sidebar = ({ export default Sidebar; ``` -声明语法定义了一个新的 React '组件'。 +声明语法定义了一个新的 React 组件。 在这里,我们硬编码了变量 `entries`,然后通过它们进行迭代,以显示每个条目的 `li` 项。 -接下来,在 `src/app/components/journal/EditEntry.jsx` 中,将内容更改为以下内容: -``` +接下来,在 `src/app/components/journal/EditEntry.jsx` 中,将原本内容更改为以下代码: +```jsx import React from 'react'; import _ from 'lodash'; @@ -126,12 +123,11 @@ const EditEntry = ({ export default EditEntry; ``` -这个 `textarea` 将始终显示我们定义的 `entry` 变量的内容 `Hello world`。 - -当前默认要显示的组件是 `src/app/components/Journal.jsx`。在该文件中,我们需要将 `Sidebar` 和 `EditEntry` 添加到 `Journal` 组件中,以便在打开网站时渲染它们。在 `Journal.jsx` 文件中,将其更改为以下内容: +`textarea` 标签定义一个多行的文本输入控件。 文本区域中可容纳无限数量的文本。这个 `textarea` 将始终显示我们定义的 `entry` 变量的内容 `Hello world`。 +当前默认显示的组件是 `src/app/components/Journal.jsx`。在该文件中,我们需要将 `Sidebar` 和 `EditEntry` 添加到 `Journal` 组件中,以便在打开网站时渲染它们。在 `Journal.jsx` 文件中,将其更改为以下代码: -``` +```jsx import React from 'react'; import Sidebar from './Sidebar'; import EditEntry from './EditEntry'; @@ -153,7 +149,7 @@ export default Journal; 在顶部导入这两个组件,然后将它们添加到渲染的内容中。 -尝试重新打开应用程序,你会发现无法编辑 `textarea` 的内容。这是因为当其值更改时,它的值没有更新。我在那里留下了一些占位符注释,我们将在那里添加一些**操作**!现在我们将使一切真正实用。 +请尝试重新打开应用程序,你会发现无法编辑 `textarea` 的内容。这是因为当其值更改时,它的值没有更新。我在那里留下了一些占位符注释,我们将在那里添加一些**操作**!现在我们将让一切真正运行起来。 ### 操作! 在这个网站的这个迭代中,我们将支持三个操作: @@ -242,22 +238,21 @@ export const selectEntry = (id) => { } ``` -这是一大段代码。这里发生了什么呢? +这一大段代码是什么意思呢? 我们正在定义应用程序可能发生的三种操作。我们将我们的 `entries` 存储在 `localStorage` 中。由于 `localStorage` 将我们的数据存储为字符串,当我们检索和保存数据时,我们必须使用 `JSON.parse` 和 `JSON.stringify` 在字符串和对象之间进行转换。 -`updateEntry` 函数具有一些逻辑,根据 `id` 来保存新条目或更新现有条目。 +1. `updateEntry` 函数具有一些逻辑,根据 `id` 来保存新条目或更新现有条目。 -`newEntry` 创建并保存存储中的新条目。 +2. `newEntry` 创建并保存存储中的新条目。 -`selectEntry` 简单地返回所选 id。 +3. `selectEntry` 简单地返回所选 id。 每个操作最终都返回一个带有 `type` 和其他数据点的对象。我们的 `localStorage` 功能模拟了基本数据库的功能。通常,这些操作将调用某个 API(应用程序编程接口)以更新或检索数据。否则,这些操作可能只是传递数据,比如 `selectEntry` 通知应用程序的其余部分用户输入的一些信息。 - 既然我们已经定义了这些操作,让我们弄清楚如何使用这些操作并相应地更新我们的应用程序状态。 -在 `src/app/reducers/index.js` 中将其更改为以下内容: +在 `src/app/reducers/index.js` 中将其原本内容更改为以下代码: ```jsx @@ -320,15 +315,15 @@ const rootReducer = combineReducers({ export default rootReducer; ``` -这又是一大段代码。在顶部,我们有一些逻辑来初始化 `entries`,如果它为空或无效的话。通常情况下,你不太可能遇到任何错误,但有一些边缘情况可能导致你的 `localStorage` 对象出现问题。 +这又是一大段代码。首先,我们有一些逻辑来初始化 `entries`,如果它为空或无效的话。通常情况下,你不太可能遇到任何错误,但有一些边缘情况可能导致你的 `localStorage` 对象出现问题。 然后,我们定义了 `initialState`,这是在应用程序打开时的默认状态(在任何用户交互之前)。 -之后,我们定义了一个 `reducer`,它接受被 `dispatch` 的任何操作,并决定如何使用操作的数据更新状态。如果你以前没有见过 `Object.assign({}, state, { DATA })` 语法,它是将 `{ DATA }` 合并到 `state` 中的新对象中(换句话说,它返回一个带有 `{ DATA }` 的更新状态)。`reducer` 返回这个更新后的状态。然后将应用程序的状态更新为新状态。 +最后,我们定义了一个 `reducer`,它接受被 `dispatch` 的任何操作,并决定如何使用操作的数据更新状态。如果你以前没有见过 `Object.assign({}, state, { DATA })` 语法,它是将 `{ DATA }` 合并到 `state` 中的新对象中(换句话说,它返回一个带有 `{ DATA }` 的更新状态)。`reducer` 返回这个更新后的状态。然后将应用程序的状态更新为新状态。 现在,实际上动作已经 **做** 了一些事情,让我们开始向组件中添加数据和动作。 -将 `src/app/containers/Journal.jsx` 更改为: +将 `src/app/containers/Journal.jsx` 中原本内容更改为以下代码: ```jsx @@ -370,7 +365,7 @@ const JournalContainer = connect( export default JournalContainer; ``` -`JournalContainer` 在这里包装了我们之前定义的 `Journal` 组件,并通过调用 `connect` 将其与Redux的数据存储绑定在一起。 +`JournalContainer` 在这里包装了我们之前定义的 `Journal` 组件,并通过调用 `connect` 将其与 Redux 的数据存储绑定在一起。 在这里,我们还传递了两个函数:`mapStateToProps` 和 `mapDispatchToProps`。我们有这些函数来过滤我们想要传递到 `Journal` 的状态的哪些部分。 `dispatch` 函数本质上是将来自给定操作的数据发送到 reducers,这些 reducers 再次决定如何获取该数据并更新应用程序的整体状态。 @@ -469,15 +464,15 @@ const EditEntry = ({ 相比之前的硬编码变量,我们现在使用了传递下来的 `props`(状态数据和调度函数)。 -现在你的应用应该是完全可用的!你可以编辑条目并创建新的条目。 +现在你的应用应该是完全可用的!你可以编辑日记条目并创建新的日记条目。 ### 连接到新页面 -由于你将来可能会发现自己需要这样做,这是如何添加到页面的方法。 +因为你将来可能想要添加新的页面,以下如何添加页面的方法。 在你的 `Sidebar` 组件中,在定义的末尾的 `` 后面添加 `About`。在文件的顶部,你会看到我们已经 `import` 了 `{ Link } from 'react-router';`。添加这个后,你就可以点击该链接,它会跳转到 `/about`。你可以在 `src/app/components/about/About.jsx` 中查看该组件。 ### 总结 -你已经成功构建了一个基本的 React + Redux 应用程序 - 包括组件、操作、减速器等!一开始,React + Redux 被认为学习曲线陡峭,所以如果你对应用程序中发生的事情仍然有疑问,那没关系。 +你已经成功构建了一个基本的 React 和 Redux 的网站了!一开始,React 和 Redux 的学习是很困难的,所以如果你对应用程序仍然有疑问,那是很正常的。 为了巩固你的理解,这里有一些你可以添加到你的应用程序的内容: @@ -485,8 +480,5 @@ const EditEntry = ({ - 在侧边栏下每个条目的列表中显示创建/编辑日期 - 为每个条目添加标题属性,并在侧边栏中显示该标题 -除此之外,你可以为这个日志应用程序添加许多功能,放弃整个日志应用程序,并使用你新获得的知识去构建完全不同的东西,通过你的操作将应用程序连接到后端服务器(而不是使用 `localStorage`)。可能性是无穷无尽的。 - - -在 `completed` 分支中查看完整的代码。 +除此之外,你可以为这个日志应用程序添加许多功能,放弃整个日志应用程序,并使用你新获得的知识去构建完全不同的东西,通过你的操作将应用程序连接到后端服务器(而不是使用 `localStorage`)。 diff --git a/pages/hackpack-web-next.md b/pages/hackpack-web-next.md new file mode 100644 index 0000000..75004f1 --- /dev/null +++ b/pages/hackpack-web-next.md @@ -0,0 +1,24 @@ +# Web Next 教程 + +## 入门指南 +本教程旨在帮助你迅速上手 [Next](https://nextjs.org),并使用 React 和 Express 制作网站。最后,你将创建一个从 [PokéApi](https://pokeapi.co/) 获取数据并属于自己的宝可梦图鉴网站! + +### 什么是 NextJS? +NextJS 是一个框架,它允许你快速开始使用 React 和服务器端代码。它带有内置功能,如路由(路由器从一个接口上收到数据包,根据数据包的目的地址进行定向并转发到另一个接口的过程)、热模块替换(允许在运行时更新各种模块,而无需进行完全刷新)、服务器端渲染(一种在用户自己的服务器上加载网站的 JavaScript 的方法)和代码分割(一种将代码拆分成多个独立文件的技术),可以提高性能,而这些功能如果自己实现可能会是一个**巨大**的痛苦。 + +### 入门 +在本地克隆此存储库并安装依赖项: + +``` +git clone https://github.com/TreeHacks/hackpack-web-next.git +``` + +如果想启动,请运行以下命令: + +``` +npm install +``` + +你可以通过访问 http://localhost:3000 打开网站。请注意,现在的终端将监视代码的更改并自动重新编译代码。尝试更改 `pages/index.js` 中的一些文本,网站会立即更改。这被称为 [热模块替换 (HMR)](https://webpack.js.org/concepts/hot-module-replacement/)! + +![image](https://user-images.githubusercontent.com/1689183/52835583-e0bc1f00-309b-11e9-8c2e-e067bd5290d4.png) diff --git a/pages/hackpack-web.md b/pages/hackpack-web.md index 145688b..d93a9a7 100644 --- a/pages/hackpack-web.md +++ b/pages/hackpack-web.md @@ -1,20 +1,20 @@ -# Web开发攻略包 +# Web 开发攻略包 ### 介绍 -欢迎来到 TreeHacks web 开发攻略包!我们将创建一个名为 TreeYaks 的应用程序,该应用程序允许用户发布内容并对其他人发布的内容进行投票。 +在本教程中,我们将创建一个名为 TreeYaks 的应用程序,该应用程序允许用户发布内容并对其他人发布的内容进行投票。 ### 设置 -Windows 用户:通过下载 Ruby 安装程序来安装 Ruby:[http://rubyinstaller.org/](http://rubyinstaller.org/)。 +Windows 用户:点击[这里](http://rubyinstaller.org/)下载 Ruby 安装程序。 -Mac 用户:Ruby 应该已经安装在您的计算机上。 +Mac 用户:Ruby 应该已经安装在你的电脑上。 -所有平台:下载攻略包后,转到 treeyaks/ 文件夹并输入 `bundle install`。然后,输入 `ruby app.rb`。现在,转到 [http://localhost:4567](http://localhost:4567)。如果您看到 TreeYaks 页面,那么您已经准备好了,一切都安装正确!如果没有,这可能意味着在安装Ruby和/或运行 `bundle install` 时出现了问题。 +所有平台:下载攻略包后,进入 `treeyaks/` 文件夹并输入 `bundle install`。然后,输入 `ruby app.rb`。然后点击[这里](http://localhost:4567)。如果你看到 TreeYaks 页面,那么你已经准备好了,一切都安装正确!如果没有,这可能意味着在安装 Ruby 或运行 `bundle install` 时出现了问题。 ## TreeYaks -我们将使用一个名为 Sinatra 的框架在 Ruby 中构建 TreeYaks。Sinatra 是用 Ruby 编写的 Web 框架,可帮助您开发 Web 应用程序。如果您以前从未使用过 Ruby,不用担心!我们将在进行的过程中解释语法。但是,如果您想了解更多关于 Ruby 的信息,请查看这些交互式 Ruby 教程: +我们将使用一个名为 Sinatra 的框架在 Ruby 中构建 TreeYaks。Sinatra 是用 Ruby 编写的 Web 框架,可帮助你开发 Web 应用程序。如果你以前从未使用过 Ruby,不用担心!我们将在进行的过程中解释语法。如果你想了解更多关于 Ruby 的信息,请查看这些交互式 Ruby 教程: [https://www.codecademy.com/learn/ruby](https://www.codecademy.com/learn/ruby) @@ -22,33 +22,33 @@ Mac 用户:Ruby 应该已经安装在您的计算机上。 ### 查看所有帖子 -我们将首先解决的第一个里程碑是查看所有帖子。在 app.rb 中,有一个名为 `Yak` 的类。Ruby 中的类具有实例变量和方法,就像 Java 或 C++ 中的类一样。每个 `Yak` 对象将代表用户发布的一条Yak。 +我们将首先实现的第一个功能是查看所有帖子。在 app.rb 中,有一个名为 `Yak` 的类。Ruby 中的类具有实例变量和方法,就像 Java 或 C++ 中的类一样。每个 `Yak` 对象将代表用户发布的一条 Yak。 ``` class Yak < ActiveRecord::Base end ``` -让我们在 `get '/'` 方法中将所有的Yaks分配给一个名为 `yaks` 的变量。这将使所有的Yaks都出现在主页上。您可以通过在 `Yak` 类上调用 `all` 方法来获取每个用户发布的所有 Yaks。 +让我们在 `get '/'` 方法中将所有的Yaks分配给一个名为 `yaks` 的变量。这将使所有的Yaks 都出现在主页上。你可以通过在 `Yak` 类上调用 `all` 方法来获取每个用户发布的所有 Yaks。 ``` get '/' do - # BEGIN YOUR CODE HERE + # 从这里开始编写代码 - # Here, you should store all the Yak's in the database in a variable called yaks. + # 在这里,你将数据库中的所有 Yak 存储到一个名为 "Yak" 的变量中。 - # END YOUR CODE HERE + # 在此结束代码 erb :index, locals: { yaks: yaks } end ``` -应该已经有一行调用 `erb` 函数的代码。`erb` 是一个特殊的函数,用于呈现显示 `yaks` 的 HTML。这就是为什么我们将 `yaks` 变量传递给它的原因 - 它将获取从数据库加载的所有yaks,并将呈现的 HTML 返回给浏览器。它呈现的 HTML 位于 `views/index.erb` 文件中。您不需要编辑此文件,但请随意更改样式以自定义主页的外观和感觉! +这里应该已经有一行调用 `erb` 函数的代码。`erb` 是一个特殊的函数,用于呈现显示 `yaks` 的 HTML。这就是为什么我们将 `yaks` 变量传递给它。 它将获取从数据库加载的所有yaks,并将显示的 HTML 返回给浏览器。它显示的 HTML 位于 `views/index.erb` 文件中。你不需要编辑此文件,但可以随意更改样式以自定义主页的外观。 ### 添加帖子 -接下来,让我们让用户添加帖子。您会注意到主页上已经有一个用于 TreeYaks 的 “创建Yak” 链接。然而,目前填写表单实际上什么都不会发生。 +接下来,让我们让用户添加帖子。你会注意到主页上已经有一个用于 TreeYaks 的 “创建 Yak” 链接。然而,目前填写表单实际上什么都不会发生。 在 `post '/new_yak'` 方法中,用户填写的表单的内容已经在 `contents` 变量中。为了完成方法的其余部分,添加代码以创建新的 `Yak`,设置实例变量,并在对象上调用 `save` 方法将其保存到数据库。 @@ -58,23 +58,23 @@ end post '/new_yak' do contents = params['contents'] - # BEGIN YOUR CODE HERE + # 从这里开始编写代码 - # Here, you should create a new yak, initialize it with the data from the form, and then save it to the database. + # 在这里,你创建一个新的 Yak,用表单中的数据对其进行初始化,然后将其保存到数据库中。 - # END YOUR CODE HERE + # 在此结束代码 redirect to('/') end ``` -在方法末尾调用的 `redirect_to` 意味着用户发布了新的 Yak 之后,我们将带他们返回到主页 - 这样他们就可以看到他们刚刚发布的 Yak! +在方法末尾调用的 `redirect_to` 意味着用户发布了新的 Yak 之后,我们将带他们返回到主页,这样他们就可以看到他们刚刚发布的 Yak! -现在,您应该能够测试所有内容。转到主页,您应该已经看到一些 Yaks。点击 “创建Yak”,添加一个新的 Yak,然后返回主页。如果您看到刚刚发布的 Yak,那么一切都很顺利! +现在,你应该能够测试所有内容。回到主页,你应该已经看到一些 Yaks。点击 “创建 Yak”,添加一个新的 Yak,然后返回主页。如果你看到刚刚发布的 Yak,那么一切都很顺利! ### 点赞和反对 -现在,让我们添加用户点赞或反对 Yaks 的功能。两者的代码将非常相似,因此让我们首先处理点赞。您会注意到每个 Yak 卡片中已经有一些 “点赞” 和 “反对” 的链接。点击 “点赞” 链接将调用 `app.rb` 中的 `post '/upvote'` 方法。 +现在,让我们添加用户点赞或反对 Yaks 的功能。两者的代码将非常相似,因此让我们首先应用点赞功能。你会注意到每个 Yak 卡片中已经有一些 “点赞” 和 “反对” 的链接。点击 “点赞” 链接将调用 `app.rb` 中的 `post '/upvote'` 方法。 @@ -82,12 +82,13 @@ end post '/upvote' do yak_id = params['yak_id'] - # BEGIN YOUR CODE HERE - - # In this section, you should increment the yak's upvotes by 1 and return the new number of upvotes in json. - # (Note: This will be called via AJAX, so you don't need to render any html or redirect to any other page.) + # 从这里开始编写代码 + + # 在这一部分,您应该将 Yak 的 upvotes 递增 1,并以 json 格式返回新的 upvotes 数量。 + # 注意:这将通过 AJAX 调用,因此您不需要呈现任何 HTML 或重定向到任何其他页面。 + + # 在此结束代码 - # END YOUR CODE HERE end ``` @@ -101,40 +102,40 @@ end post '/downvote' do yak_id = params['yak_id'] - # BEGIN YOUR CODE HERE - - # In this section, you should decrement the yak's upvotes by 1. - # This will be called via AJAX, so you don't need to render any html or redirect to any other page. - # Hint: You should be able to reuse some code from the '/upvote' method. - - # END YOUR CODE HERE - end + # 从这里开始编写代码 + + # 在这一部分,您应该将 Yak 的点赞票数减 1。 + # 这将通过 AJAX 调用,因此您不需要渲染任何 HTML 或重定向到任何其他页面。 + # 提示:您可以重复使用 "/upvote" 方法中的一些代码。 + + # 在此结束代码 +end ``` ### 排序 -对于最后一个功能,我们将添加按点赞数量排序Yaks的功能,以便用户可以轻松找到最受欢迎的Yaks。查看 `get '/hot'` 方法。当用户想查看所有Yaks时,将调用此方法,但按点赞数量降序排序。 +对于最后一个功能,我们将添加按点赞数量排序 Yaks 的功能,以便用户可以轻松找到最受欢迎的Yaks。查看 `get '/hot'` 方法。当用户想查看所有Yaks时,将调用此方法,但按点赞数量降序排序。 ``` get '/hot' do - # BEGIN YOUR CODE HERE + # 从这里开始编写代码 - # Here, you should use the order method on the Yak class to get all the Yaks ordered by upvotes. - # The order method takes one parameter, which is the field you want to order by. + # 在这里,你应该使用 Yak 类的 order 方法来获取所有按 upvotes 排序的 Yaks。 + # order 方法需要一个参数,即你想要排序的字段。 - # END YOUR CODE HERE + # 在此结束代码 end ``` ``` get '/new' do - # BEGIN YOUR CODE HERE + # 从这里开始编写代码 - # Here, you should use the order method on the Yak class to get all the Yaks ordered by it's created_at field. - # The order method takes one parameter, which is the field you want to order by. + # 在这里,你应该使用 Yak 类的 order 方法来获取所有按 created_at 字段排序的 Yak。 + # order 方法需要一个参数,即你想要排序的字段。 - # END YOUR CODE HERE + # 在此结束代码 end ``` diff --git a/pages/hardware_hackpack.md b/pages/hardware_hackpack.md index e5c01fe..72d1f63 100644 --- a/pages/hardware_hackpack.md +++ b/pages/hardware_hackpack.md @@ -1,20 +1,20 @@ -# 树莓派 Pico 教程 +# 硬件教程 -这是一个关于如何使用微控制器,特别是树莓派 Pico 的初学者教程。无论你的经验水平如何,你都可以理解我们的教学内容。我们在这里打下一些基础,并将在黑客马拉松中举办更多与硬件相关的活动。我们希望你从这个 Hackpack 中学到的技能能够帮助你在硬件方面打好基础,并产生自己的创意想法! +这是一个关于如何使用像树莓派 Pico 这样的微控制器的初学者教程。无论是否有这方面的基础,你都可以轻易理解我们的教学内容。我们在这里打下一些基础,并将在之后的 ***AdventureX*** 青年创业大赛中举办更多与硬件相关的活动。希望你从本教程中学到的技能能够帮助你在硬件方面打好基础,并产生自己的创意想法! -#### 部件: +#### 需要使用到的零件与材料: 基本设置: 1. 树莓派 Pico 2. 微型 USB 电缆 3. 你的电脑! -制作 Pico 项目还需要以下部件: +制作 Pico 项目还需要以下材料: 1. 舵机电机 2. 杜邦线(母头对母头和母头对公头) 3. 红外传感器 4. 面包板 -# ⚙️ 设置 +# 设置 1) 从 [https://thonny.org/](https://thonny.org/) 下载 Thonny: 点击屏幕右上角的下载按钮,选择适用于你操作系统的下载按钮。 @@ -58,7 +58,7 @@ ![thonnyconnect](https://user-images.githubusercontent.com/93958307/209353975-ccd6c73e-5579-4516-95b4-28d00ec2a4f3.gif) -这是 blink.py 的结果-你的 Pico 的内置 LED 会周期性地闪烁! +这是 blink.py 的结果:你的 Pico 的内置 LED 会周期性地闪烁! ![picoblink](https://user-images.githubusercontent.com/93958307/209513748-d9da48de-b6f2-4129-8602-bc48b2bc1d44.gif) @@ -69,24 +69,23 @@ 所以现在,每当我将 Pico 连接到电脑时,它都会自动运行 main.py,Pico 上的 LED 就会开始闪烁。 //视频展示我连接和断开它 -#### 恭喜你在你的 Pico 上运行了一个 Micropython 程序!! 🎉 +#### 恭喜你在你的 Pico 上运行了一个 Micropython 程序!! -现在,你可以尝试使用不同的 Micropython 程序,并让你的 Pico 做一些很酷的事情。在下一节中,我们将介绍如何将你的 Pico 进一步连接到其他对象,从而可以构建更多的项目! +现在,你可以尝试使用不同的 Micropython 程序,并让你的 Pico 做一些很酷的事情。在下一节中,我们将介绍如何将你的 Pico 进一步连接到其他设备,从而可以构建更多的项目! -### ⚡ Pico +### Pico Pico 是一款微控制器,类似于 Arduino 或 Adafruit 的著名 M4 Feather Express。它具有数字输入和输出引脚(GPIO)以及模拟引脚(ADC)。这些引脚是当我们将 Pico 连接到其他对象,如传感器、电机、LED 等时使用的。你可以在它的数据表中了解更多信息: [Pico 数据表](https://datasheets.raspberrypi.com/pico/pico-datasheet.pdf) Screenshot 2022-12-25 at 12 36 18 PM -# 例子: 红外传感器 + 舵机电机 +# 示例: 红外传感器 + 舵机电机 我们将演示如何使用红外传感器与舵机电机结合使用。我们最终的结果将是一个在物体靠近传感器时启动的舵机电机! ## 舵机 #### 连接: -如果你以前没有使用过面包板并想了解更多信息,你可以查看...,(尽管这不是必需的) 要连接舵机,请参照下面的图像: ![picoservo](https://user-images.githubusercontent.com/93958307/209617753-6e762a2f-15ff-4fe4-b924-08c4fc5ca186.png) @@ -101,7 +100,7 @@ Pico 是一款微控制器,类似于 Arduino 或 Adafruit 的著名 M4 Feather [演示视频](https://user-images.githubusercontent.com/93958307/209615678-ab9aa838-0db8-4334-8671-44983f771de6.mov) #### 代码 -请查看 servomotor.py 文件中的代码。通过将代码保存为主板上的 main.py 文件,或通过 Thonny 运行它,你可以运行代码,就像我们之前用 'blink' 示例一样。 +请查看 servomotor.py 文件中的代码。将其保存在主板上的 main.py 文件,或者通过 Thonny 运行它,就像我们之前用 “blink“ 示例一样。 #### 演示 @@ -129,7 +128,7 @@ Pico 是一款微控制器,类似于 Arduino 或 Adafruit 的著名 M4 Feather #### 代码 -请查看 irservo.py 文件中的代码。通过将代码保存为主板上的 main.py 文件,或通过 Thonny 运行它,你可以运行代码,就像我们之前用 'blink' 示例一样。 +请查看 irservo.py 文件中的代码,将代码保存在主板上的 main.py 文件里,或通过 Thonny 运行它,就像我们之前用 'blink' 示例一样。 #### 演示 请注意,当有干扰时,红外传感器上会亮起两个红灯,而在没有干扰时只会亮起一个!