@algonauti/ember-active-storage

中文文档
3.0.0发布于 2026/10/17MITTypeScriptCommonJS近 30 天下载 3817

用活性存储器为 Ember.js 应用程序提供动力

中文使用文档
文档目录14 节
  1. 安装
  2. 使用量
  3. 活动
  4. XHR 对象
  5. 元数据
  6. 配置
  7. 正在发送认证信头
  8. 类型脚本
  9. 捐款
  10. 安装
  11. 线性
  12. 正在测试
  13. 运行测试应用程序
  14. 许可证

嵌入式活性存储

CI Ember Observer Score

安装

ember install @algonauti/ember-active-storage

使用量

附加词提供了 activeStorage 服务允许您:

  • 将文件发送给您的 Rails 后端的直接上传控制器;
  • 上传进度事件.

假设您的模板有如下文件输入:

<input type="file" {{on "change" (fn this.upload)}} />

和你的模具有一个 avatar 属性定义为 has_one_attached :avatar ,然后在您的组件(或控制器)中 upload 动作看起来像:

import Component from '@glimmer/component';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { service } from '@ember/service';

export default class UploadComponent extends Component {
  @service
  activeStorage;

  @tracked
  uploadProgress = 0;

  @action
  upload(event) {
    const files = event.target.files;
    if (files) {
      const directUploadURL = '/rails/active_storage/direct_uploads';

      for (var i = 0; i < files.length; i++) {
        this.activeStorage
          .upload(files.item(i), directUploadURL, {
            onProgress: (progress, event) => {
              this.uploadProgress = progress;
            },
          })
          .then((blob) => {
            const signedId = blob.signedId;

            this.model.avatar = signedId;
          });
      }
    }
  }
}
  • directUploadURL 是路径引用 ActiveStorage::DirectUploadsController 在您的 Rails 后端( 或上面的自定义) .
  • 这个 uploadProgress 属性将持有 0 到 100 之间的值,您可以在模板中用于显示上传进度.
  • 之后 upload 承诺是解决的 signedId 设置在您的模型中,当 model.save() 启动时, Rails 后端会使用此 signedId 关联 ActiveStorage::Attachment 记录到你的后端模型的记录.

活动

loadstart, (中文(简体) ), load, (中文(简体) ), loadend, (中文(简体) ), error, (中文(简体) ), abort, (中文(简体) ), timeout 事件引用 onLoadstart, (中文(简体) ), onLoad, (中文(简体) ), onLoadend, (中文(简体) ), onError, (中文(简体) ), onAbort, (中文(简体) ), onTimeout 相应. 例如: 如果你想用这个 loadend 在你的应用中,你可以使用像;

import Component from '@glimmer/component';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { service } from '@ember/service';

export default class UploadComponent extends Component {
  @service
  activeStorage;

  @tracked
  uploadProgress = 0;

  @action
  upload(event) {
    const files = event.target.files;
    if (files) {
      const directUploadURL = '/rails/active_storage/direct_uploads';

      for (var i = 0; i < files.length; i++) {
        this.activeStorage
          .upload(files.item(i), directUploadURL, {
            onProgress: (progress, event) => {
              this.uploadProgress = progress;
            },
            onLoadend: (event) => {
              debug(`Event captured ${event}`); // https://developer.mozilla.org/en-US/docs/Web/API/ProgressEvent
            },
          })
          .then((blob) => {
            const signedId = blob.signedId;

            this.model.avatar = signedId;
          });
      }
    }
  }
}

XHR 对象

如果你需要实际 XHR object 在你的应用程序,你可以使用 onXHROpened 活动。 它还原 XHR object 参考文献。 例如:

import Component from '@glimmer/component';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { service } from '@ember/service';

export default class UploadComponent extends Component {
  @service
  activeStorage;

  @tracked
  uploadProgress = 0;

  @tracked
  xhrs = [];

  @action
  upload(event) {
    const files = event.target.files;
    if (files) {
      const directUploadURL = '/rails/active_storage/direct_uploads';

      for (var i = 0; i < files.length; i++) {
        this.activeStorage
          .upload(files.item(i), directUploadURL, {
            onProgress: (progress, event) => {
              this.uploadProgress = progress;
            },
            onXHROpened: (xhr) => {
              this.xhrs.push(xhr);  // so you can loop over this.xhrs and invoke abort()
            },
          })
          .then((blob) => {
            const signedId = blob.signedId;

            this.model.avatar = signedId;
          });
      }
    }
  }
}

元数据

ActiveStorage支持直接上传的元数据. 这是为铁路应用提供更多信息的好方法.

class DirectUploadsController < ActiveStorage::DirectUploadsController
  def create
    # blob_args[:metadata]['additional_type']
    # => my_type
    blob = ActiveStorage::Blob.create_before_direct_upload!(**blob_args)
    render json: direct_upload_json(blob)
  end
end
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { service } from '@ember/service';

export default class UploadComponent extends Component {
  @service
  activeStorage;

  @action
  upload(event) {
    const files = event.target.files;
    if (files) {
      const directUploadURL = '/rails/active_storage/direct_uploads';

      for (var i = 0; i < files.length; i++) {
        this.activeStorage
          .upload(files.item(i), directUploadURL, {
            metadata: {
              additional_type: 'my_type'
            },
          })
          .then((blob) => {
            const signedId = blob.signedId;

            this.model.avatar = signedId;
          });
      }
    }
  }
}

配置

有一个 ember-active-storage 仅使用一个参数的 ENV 配置 url。通过此配置,您现在可以省略上传的 URL 。 例如:

ENV['ember-active-storage'] = {
  url: 'http://your-domain/rails/active_storage/direct_uploads',
};

现在可以不用上传url调用上传功能.

import Component from '@glimmer/component';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { service } from '@ember/service';

export default class UploadComponent extends Component {
  @service
  activeStorage;

  @tracked
  uploadProgress = 0;

  @action
  upload(event) {
    const files = event.target.files;
    if (files) {
      for (var i = 0; i < files.length; i++) {
        this.activeStorage
          .upload(files.item(i), {
            onProgress: (progress, event) => {
              this.uploadProgress = progress;
            },
          })
          .then((blob) => {
            const signedId = blob.signedId;

            this.model.avatar = signedId;
          });
      }
    }
  }
}

正在发送认证信头

相当常见的是,你想通过认证来保护你的铁路后端上的直接上传端点. 如果是这样的话 activeStorage 服务需要发送认证头和直接上传请求.

要做到这一点,你需要延长 activeStorage 页:1 headers 计算财产。 例如,如果你在使用 凹凸-平地,这将是两个步骤的过程。 首先你需要定义一个 authenticatedHeaders 计算您的属性 session 服务,像这样:

// app/services/session.js
import Service from '@ember/service';
import { service } from '@ember/service';

export default class MySessionService extends Service {
  @service
  session;

  get authenticatedHeaders() {
    const { access_token } = this.session.authenticated;

    return { Authorization: `Bearer ${access_token}` };
  }
}

然后,你会别名 财产在你的 activeStorage 服务,像这样:

// app/services/active-storage.js
import ActiveStorage from '@algonauti/ember-active-storage/services/active-storage';
import { service } from '@ember/service';

export default class ActiveStorageService extends ActiveStorage {
  @service('my-session')
  session;

  get headers() {
    this.session.authenticatedHeaders;
  }
}

另注:如果下载端点也受到保护,而您正在使用 ajax 请求来下载文件,那么不要忘记在请求中也包含相同的信头.

类型脚本

附加语用TypeScript来写作,并用自己类型的声明来写出.

import Component from '@glimmer/component';
import { service } from '@ember/service';
import type { ActiveStorageService, UploadOptions } from '@algonauti/ember-active-storage';

export default class UploadComponent extends Component {
  @service declare activeStorage: ActiveStorageService;

  upload = async (event: Event) => {
    const file = (event.target as HTMLInputElement).files?.[0];

    if (file) {
      const options: UploadOptions = {
        onProgress: (progress) => console.log(progress),
      };
      const blob = await this.activeStorage.upload(file, '/rails/active_storage/direct_uploads', options);

      console.log(blob.signedId);
    }
  };
}

导出类型 : ActiveStorageConfig, (中文(简体) ), DirectUploadData, (中文(简体) ), DirectUploadResponse, (中文(简体) ), Headers, (中文(简体) ), RequestOptions, (中文(简体) ), UploadEventHandlers, (中文(简体) ), UploadOptions, (中文(简体) ), UploadResponse 财务报告和审定财务报表 UploadResponseOptions。 。 。 . ActiveStorageService, (中文(简体) ), Blob, (中文(简体) ), FileChecksum, (中文(简体) ), Uploader 编辑 uploadResponse 测试帮助也被导出.

捐款

安装

  • git clone <repository-url>
  • cd ember-active-storage
  • pnpm install

线性

  • pnpm lint
  • pnpm lint:fix

正在测试

  • pnpm test 运行当前 Ember 版本的测试套件
  • cd test-app && ember try:each – 对照多个 Ember 版本运行测试套件

运行测试应用程序

关于使用ember-cli的更多信息,请访问 https://ember-cli.com/ (中文(简体) )。 。 。 .

许可证

本项目根据以下规定获得许可证: MIT 许可证。 。 。 .

版本与发布记录

@algonauti/ember-active-storage 共发布 10 个版本,首次发布于 2021/03/23;过去 12 个月发布了 1 个版本。

版本发布日期距今
3.0.0latest2026/10/1722 天前
2.3.02023/06/063 年前
2.2.12023/06/063 年前
2.2.02022/08/274 年前
2.1.12021/12/024 年前
2.0.32021/09/225 年前

关于 @algonauti/ember-active-storage 的常见问题

@algonauti/ember-active-storage 是什么?

用活性存储器为 Ember.js 应用程序提供动力

如何安装 @algonauti/ember-active-storage?

在项目目录运行 npm install @algonauti/ember-active-storage,或使用 pnpm add / yarn add / bun add。

@algonauti/ember-active-storage 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@algonauti/ember-active-storage 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@algonauti/ember-active-storage 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >= 20.19。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@algonauti/ember-active-storage 可以商用吗?

@algonauti/ember-active-storage 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@algonauti/ember-active-storage 的下载量有多少?

根据 npm 官方下载统计,@algonauti/ember-active-storage 在 2026/10/06 – 2026/11/04 这 30 天内被下载 3,817 次,日均约 127 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@algonauti/ember-active-storage 还在维护吗?

最新版本 3.0.0 发布于 2026/10/17(22 天前);至今共发布 10 个版本,其中过去 12 个月发布了 1 个;首次发布于 2021/03/23。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。