【问题标题】:Ember.js and image uploadingEmber.js 和图片上传
【发布时间】:2019-03-29 10:58:19
【问题描述】:

我在 Ember.js 中上传图片时遇到问题

我有一个创建用户的表单:

<div class="container">
<form onsubmit={{action "createUser"}} enctype="multipart/form-data">
  <div class="form-group">
    <label for="firstName">First name: </label>
    {{input type="text" class="form-control" id="firstName" required="true" value=firstName}}
  </div>
  <div class="form-group">
    <label for="lastName">Last name: </label>
    {{input type="text" class="form-control" id="lastName"  required="true" value=lastName}}
  </div>
  <div class="form-group">
    <label for="age">Age: </label>
    {{input type="number" class="form-control" id="age"  required="true" value=age}}
  </div>
  <div class="form-group">
    <label for="job">Job: </label> 
    {{input type="text" class="form-control" id="job"  required="true" value=job}}
  </div>
  <div class="form-group">
    <label for="image">Picture: </label> 
    {{input type="file" class="form-control" id="image" value=image}}
  </div>
  <button type="submit" class="btn btn-info">Create</button>
</form>

我知道我应该用 base64 对图像进行编码,但我不知道该怎么做,因为我以前从未这样做过。

在视图中,这就是我试图获取图像的方式(我知道这不是我应该做的,但我不知道该怎么做):

<div class="container">
  <h1>{{model.firstName}} {{model.lastName}}</h1>
  <p>Age: {{model.age}} years old</p>
  <p>Job: {{model.job}}</p>
  <img src="{{model.image}}" alt="img" id="image">
</div>

有什么想法、建议、帮助吗?


编辑:

actions: {
  createUser(event) {
    event.preventDefault();
    let user = this.store.createRecord('user', {
      firstName: this.firstName,
      lastName: this.lastName,
      age: this.age,
      job: this.job,
      image: this.image
    });
    user.save().then (() => {
      this.transitionToRoute('user', user.id);
    });
  }
}

【问题讨论】:

  • 您可以展示您的createUser 操作吗?您的后端对您的图片有何期望?
  • 我在原始帖子中添加了我的 createUser 操作。实际上我没有后端,我正在使用 mirage,我不需要保存我正在创建的数据。
  • mirage 仅用于测试。最后不保存你创建的东西是没有用的,对吧?虽然海市蜃楼很有用,但您仍然需要了解您的实际后端应该如何工作。对于图像,我通常会在模型中放置一个 URI。您提到了一些关于 base64 的内容,但没有详细说明。你能解释一下你来到base64,你想要什么?
  • 嗯,这只是一个练习,我不需要后端所以......但如果我必须这样做,你建议使用什么?基本上有人向我解释说我应该对我的图像进行编码并将结果放在一个字符串中,这就是我卡住的地方????

标签: ember.js ember-data ember-cli


【解决方案1】:

使用ember-file-upload 插件。该插件负责将它们编码为Base64 数据url。在您的情况下,请按照以下步骤操作,

hbs form page:

<form onsubmit={{action 'createUser'}}>
  <div class="form-group">
    <label for="firstName">First name: </label>
    {{input type="text" class="form-control" id="firstName" required="true" value=firstName}}
  </div>

  ...
  //other input fields
  ...

  {{#file-upload name="avatar"
                 accept="image/*"
                 onfileadd=(action 'setAvatar')}}

    // preview image before uploading
    {{#if avatar}}
      <img src={{avatar}}
      <a id="upload-avatar">Add a photo</a>
    {{else}}
      <a id="upload-avatar">Add a photo</a>
    {{/if}}

  {{/file-upload}}
  <button type="submit">Create</button>
</form>

hbs view page:

<div class="container">
  <h1>{{model.firstName}} {{model.lastName}}</h1>
  <p>Age: {{model.age}} years old</p>
  <p>Job: {{model.job}}</p>
  <img src={{model.image}} alt="img" id="image">
</div>

js:

import Controller from '@ember/controller';

export default Controller.extend({
  avatarFile: null,
  actions: {
    createUser(event) {
      event.preventDefault();
      // upload file to backend
      let file = this.get('avatarFile');
      // make a api call to the url `/upload` (modify the url as you wish)
      file.upload('/upload').then((response) => {
        // save user model once the image is been uploaded successfully to the server
        let user = this.store.createRecord('user', {
          firstName: this.firstName,
          ...
          // get the image_url from backend response
          image: response.image_url
        });
        user.save().then((response) => {
          // get the user_id in response
          this.transitionToRoute('user', response.user_id);
        });
      });
    },
    setAvatar(file) {
      this.set('avatarFile', file);

      // Set the URL so we can see a preview
      file.readAsDataURL().then((url) => {
        this.set('avatar', url);
      });
    }
  }
});

你可以参考整个文档here

【讨论】:

  • 感谢您的帮助 :) 当我尝试创建新用户时收到此错误消息“未捕获的 TypeError:file.upload 不是函数”,知道为什么吗?
  • 确保this.set('avatarFile', file); 行出现在setAvatar 操作中?
  • 请关注此文档http://adopted-ember-addons.github.io/ember-file-upload/docs/integration
  • 仍然是同样的错误,即使在阅读文档大约 30 次之后哈哈。我实在想不通!感谢您的询问
【解决方案2】:

替换

{{input type="file" class="form-control" id="image" value=image}}

<input type="file" class="form-control" id="image" onchange={{action "uploadFile"}}/>
<br> Chosen image is <br>
<img src={{image}} />

这将在选择图像时触发 uploadFile 操作。 在您的 js 文件中,将操作添加为,

actions: {
  uploadFile: function(event) {
    var self = this;
    const reader = new FileReader();
    const file = event.target.files[0];
    let imageData;

    reader.onload = function(){
      imageData = reader.result;
      self.set('image', imageData);
    };

    if (file) {
      reader.readAsDataURL(file);
    }
  }
}

来源:https://stackoverflow.com/a/40370830/2824131

【讨论】:

  • 哇,非常感谢!这完全有效,感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2018-10-27
  • 1970-01-01
  • 2019-02-19
  • 2010-12-10
  • 2016-02-05
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
相关资源
最近更新 更多