Ember 资源和故障排除

我们最后的 Ember 文章为您提供了一系列资源列表,您可以使用这些资源来进一步学习,以及一些有用的故障排除和其他信息。

先决条件

至少建议您熟悉核心 HTMLCSSJavaScript 语言,并了解 终端/命令行

更深入地了解现代 JavaScript 特性(如类、模块等)将非常有益,因为 Ember 大量使用了它们。

目标 提供更多资源链接和故障排除信息。

更多资源

一般故障排除、陷阱和误解

这远非一个详尽的列表,但它是在撰写本文时(最新更新,2020 年 5 月)出现的一些事项的列表。

如何调试框架中发生的事情?

对于框架特定的事项,可以使用 ember-inspector 插件,它允许检查

  • 路由和控制器
  • 组件
  • 服务
  • Promise
  • 数据(例如,来自远程 API — 默认情况下来自 ember-data)
  • 弃用信息
  • 渲染性能

对于一般的 JavaScript 调试,请查看我们的 JavaScript 调试指南 以及与 浏览器其他调试工具 的交互。在任何默认的 Ember 项目中,将有两个主要的 JavaScript 文件,vendor.js{app-name}.js。这两个文件都是使用源映射生成的,因此当您打开 vendor.js{app-name}.js 搜索相关代码时,当设置断点时,源映射将被加载,并且断点将放置在预编译代码中,以便更容易地与您的项目代码相关联。

有关源映射、为什么需要它们以及 ember-cli 如何使用它们,请参阅 高级用法:资产编译 指南。请注意,源映射默认启用。

ember-data 预装了;我需要它吗?

一点也不。虽然 ember-data 解决了任何处理数据的应用程序都会遇到的最常见问题,但可以自己构建前端数据客户端。一个常见的替代方案是任何功能齐全的前端数据客户端 Fetch API

使用框架提供的设计模式,使用 fetch()Route 将如下所示

js
import Route from "@ember/routing/route";

export default class MyRoute extends Route {
  async model() {
    let response = await fetch("some/url/to/json/data");
    let json = await response.json();

    return {
      data: json,
    };
  }
}

有关 在此处指定 Route 的模型 的更多信息。

为什么我不能只使用 JavaScript?

这是 Ember 人员从以前有 React 经验的人那里听到的常见的问题。虽然从技术上讲可以使用 JSX 或任何其他形式的 DOM 创建,但还没有任何东西像 Ember 的模板系统那样强大。有意为之的极简主义迫使做出某些决定,并允许更一致的代码,同时使模板更具结构性,而不是让它们充满定制逻辑。

另请参阅:ReactiveConf 2017:Glimmer VM 的秘密

mut 帮助程序的状态如何?

mut 在本教程中没有介绍,实际上是从 Ember 从双向绑定数据转向更常见且更容易理解的单向绑定数据流的过渡时期遗留下来的包袱。可以将其视为在构建时进行的转换,它使用 setter 函数包装其参数。

更具体地说,使用 mut 允许声明仅模板的设置函数

hbs
<Checkbox
  @value={{this.someData}}
  @onToggle={{fn (mut this.someData) (not this.someData)}}
/>

而如果没有 mut,则需要一个组件类

js
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { action } from "@ember/object";

export default class Example extends Component {
  @tracked someData = false;

  @action
  setData(newValue) {
    this.someData = newValue;
  }
}

然后将在模板中这样调用它

hbs
<Checkbox @data={{this.someData}} @onChange={{this.setData}} />

由于使用 mut 的简洁性,可能希望使用它。但是,mut 具有不自然的语义,并且在其存在期间引起了很多混淆。

已经有一些新想法被整合到插件的形式中,这些插件使用公共 API,ember-set-helperember-box。这两个插件都试图通过引入更明显/“更少魔法”的概念来解决 mut 的问题,避免构建时转换和隐式 Glimmer VM 行为。

使用 ember-set-helper

hbs
<Checkbox @value={{this.someData}} @onToggle={{set this "someData" (not
this.someData)}} />

使用 ember-box

hbs
{{#let (box this.someData) as |someData|}}
  <Checkbox
    @value={{unwrap someData}}
    @onToggle={{update someData (not this.someData)}}
  />
{{/let}}

请注意,这些解决方案在社区成员中并不特别常见,总的来说,人们仍在努力为在仅模板的上下文中设置数据找到一个符合人体工程学且简单的 API,而无需支持 JS。

控制器的目的是什么?

控制器单例,可以帮助管理活动路由的渲染上下文。从表面上看,它们的功能与组件的后台 JavaScript 非常相似。控制器(截至 2020 年 1 月)是管理 URL 查询参数的唯一方法。

理想情况下,控制器的职责应该相当轻,尽可能地委托给组件和服务。

路由的目的是什么?

一个 路由 表示用户在应用程序中从一个地方导航到另一个地方时 URL 的一部分。路由只有几个职责

  • 加载渲染路由(或视图子树)所需的最少数据
  • 控制对路由的访问并在必要时重定向。
  • 处理来自最少必要数据的加载和错误状态。

路由只有 3 个生命周期钩子,所有这些都是可选的

  • beforeModel — 控制对路由的访问。
  • model — 加载数据的地方。
  • afterModel — 验证访问权限。

最后,路由能够处理配置 model 导致的常见事件

  • loading — 当 model 钩子正在加载时该做什么。
  • error — 当 model 中抛出错误时该做什么。

loadingerror 都可以渲染默认模板以及在应用程序其他地方定义的自定义模板,从而统一加载/错误状态。

有关 路由可以执行的所有操作的更多信息,请参阅 API 文档