将base64字符串传递给AngularJS中的对象属性 [英] Passing base64 string to object's attribute in AngularJS

查看:24
本文介绍了将base64字符串传递给AngularJS中的对象属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过输入字段上传图像,将图像的 base64 绑定到一个变量,然后将该变量添加到对象的属性中,以便我可以将其存储在我的 Firebase 数据库中.

输入表单&对象字段:

 

<h3>新剧集</h3><table class=""><tr><td class="labelField">名称</td><td><input type='text' ng-model='episode.name'></td></tr><tr><td class="labelField">Title</td><td><input type='text' ng-model='episode.title'></td></tr><tr><td class="labelField">描述</td><td><input type='text' ng-model='episode.shortDescription'></td></tr><tr><td class="labelField">时间</td><td><input type='text' ng-model='episode.time'></td></tr></tbody><img src="../images/placeholder.png" id="pano"><!-- 开始上传图片文件--><td class="labelField">图像</td><span class="btn btn-default btn-file"><input type="file" accept="image/*" capture="camera" id="file-upload"></span><div id="spin"></div><div class='btn btn-warning' ng-click='createEpisode()'>创建剧集

上传到 Firebase 的服务:

'use strict';app.service('Uploader', ['$firebase', 'FIREBASE_TEST_URL', function($firebase, FIREBASE_TEST_URL) {var ref = new Firebase(FIREBASE_TEST_URL);var 剧集 = $firebase(ref);返回 {全部:剧集,创建:功能(剧集){location.reload();//添加到firebase数据库返回剧集.$add(episode);},删除:函数(episodeId){location.reload();返回剧集.$remove(episodeId);},更新:功能(剧集){location.reload();返回剧集.$保存(剧集);}};}]);

具有图像文件处理等的控制器:

'use strict';app.controller('UploadCtrl', ['$scope', 'Uploader', function ($scope, Uploader) {$scope.episodes = Uploader.all;$scope.createEpisode = function(){Uploader.create($scope.episode).then(function(data){$scope.episode.name = '';$scope.episode.title = '';$scope.episode.description = '';$scope.episode.time = '';$scope.episode.img1 = $scope.episodeImgData;});};$scope.deleteEpisode = function(episodeId){bootbox.confirm('你确定要删除这一集吗?', function(result) {如果(结果 === 真){Uploader.delete(episodeId).then(function(data){console.log('剧集删除成功!');});}});};$scope.updateEpisode = function(episode) {Uploader.update($scope.episode).then(function(data) {控制台日志(剧集);console.log('剧集更新成功.');});};$scope.selectEpisode = 函数(对象){$scope.selectedEpisode = 对象;setTimeout(function(){ $scope.$apply($scope.selectedEpisode = object); });};//******************************************************************************************////开始图片上传:https://github.com/firebase/firepano/blob/gh-pages/firepano.js////要求:index.js 中的 app/scripts/js/crypto.jsvar spinner = new Spinner({color: '#ddd'});$scope.episodeImgData = '../images/defaultplaceholder.png';函数 handleFileSelectAdd(evt) {var f = evt.target.files[0];var reader = new FileReader();reader.onload = (function(theFile) {返回函数(e){var filePayload = e.target.result;var hash = CryptoJS.SHA256(Math.random() + CryptoJS.SHA256(filePayload));$scope.episodeImgData = e.target.result;document.getElementById('pano').src = $scope.episodeImgData;控制台日志($scope.episodeImgData);};})(F);reader.readAsDataURL(f);}函数 handleFileSelectEdit(evt) {var f = evt.target.files[0];var reader = new FileReader();reader.onload = (function(theFile) {返回函数(e){var filePayload = e.target.result;var hash = CryptoJS.SHA256(Math.random() + CryptoJS.SHA256(filePayload));$scppope.episodeImgData = e.target.result;document.getElementById('pano2').src = $scope.episodeImgData;$scope.selectedEpisode.img1 = $scope.episodeImgData;控制台日志($scope.episodeImgData);};})(F);reader.readAsDataURL(f);}$(函数(){$('#spin').append(spinner);document.getElementById('file-upload').addEventListener('change', handleFileSelectAdd, false);document.getElementById('file-upload2').addEventListener('change', handleFileSelectEdit, false);});//结束图片上传:https://github.com/firebase/firepano/blob/gh-pages/firepano.js////****************************************************************************************//}]);

表单中除img1外的所有属性都保存到DB中.当更新按钮被点击时,我想我可以将 episodeImgData 传递给对象(img1 变量)进行保存,但它根本不保存任何东西(只是与情节.name 相关的表单变量等).做到这一点的最佳方法是什么?我正在使用 FirePano 示例的一部分(https://github.com/firebase/firepano/blob/gh-pages/firepano.js) 用于图像处理.

解决方案

更新 (20160519):Firebase 刚刚发布了一项名为 Firebase 存储.这允许您将图像和其他非 JSON 数据上传到专用存储服务.我们强烈建议您使用它来存储图像,而不是将它们作为 base64 编码数据存储在 JSON 数据库中.

那个代码有很多小问题.

  • 因为你的剧集是一个数组,你可以用$asArray来创建,否则它不会有$add方法:var episodes =$firebase(ref).$asArray();
  • 您在将数据发送到服务器之前调用了 location.reload()
  • 您的文件上传处理程序没有为我触发
  • firepano 中提到了微调器

我认为前两个是最大的.但是,如果您不提供重现问题的最小示例,则很难找到这种类型的问题.我现在为你做了.

最后,代码不是太大,这里分享一下:

var app = angular.module('myapp', ['firebase']).service('上传者', 函数($firebase) {var ref = new Firebase('http://.firebaseio.com/');var episodes = $firebase(ref).$asArray();返回 {全部:剧集,创建:功能(剧集){//添加到firebase数据库返回剧集.$add(episode);}};}).controller('UploadCtrl', function ($scope, Uploader) {$scope.episodes = Uploader.all;$scope.createEpisode = function() {如果($scope.episodeImgData){$scope.episode.img1 = $scope.episodeImgData;}Uploader.create($scope.episode);};$scope.handleFileSelectAdd = function(evt) {var f = evt.target.files[0];var reader = new FileReader();reader.onload = (function(theFile) {返回函数(e){var filePayload = e.target.result;$scope.episodeImgData = e.target.result;document.getElementById('pano').src = $scope.episodeImgData;};})(F);reader.readAsDataURL(f);};document.getElementById('file-upload').addEventListener('change', $scope.handleFileSelectAdd, false);});

对应的(正文)HTML:

<div class="row modalDetail" ng-controller='UploadCtrl'><h3>新剧集</h3><table class="" ng-model='episode'><tr><td class="labelField">名称</td><td><input type='text' ng-model='episode.name'></td></tr><tr><td class="labelField">Title</td><td><input type='text' ng-model='episode.title'></td></tr><tr><td class="labelField">描述</td><td><input type='text' ng-model='episode.shortDescription'></td></tr><tr><td class="labelField">时间</td><td><input type='text' ng-model='episode.time'></td></tr></tbody><td class="labelField">图像</td><span class="btn btn-default btn-file"><input type="file" accept="image/*" capture="camera" id="file-upload"></span><div class='btn btn-warning' ng-click='createEpisode()'>创建剧集</div><br/><img id="全景">

如果使用可选图像数据创建剧集,这是一个有效的演示:http://jsbin.com/roriwu/7.

I'm trying to upload an image via an input field, tie the base64 of the image to a variable, then add that variable to the attribute of an object so I can store it in my Firebase db.

Input form & field for object:

      <div class="row modalDetail">
              <h3>New Episode</h3>
              <table class="">
                <tbody>
                  <tr>
                    <td class="labelField">Name</td>
                    <td><input type='text' ng-model='episode.name'></td>
                  </tr>
                  <tr>
                    <td class="labelField">Title</td>
                    <td><input type='text' ng-model='episode.title'></td>
                  </tr>
                  <tr>
                    <td class="labelField">Description</td>
                    <td><input type='text' ng-model='episode.shortDescription'></td>
                  </tr>
                  <tr>
                    <td class="labelField">Time</td>
                    <td><input type='text' ng-model='episode.time'></td>
                  </tr>
                </tbody>
              </table>
              <img src="../images/placeholder.png" id="pano">

              <!-- START Image File Upload -->        
                <td class="labelField">Image</td>
                <span class="btn btn-default btn-file">
                  <input type="file" accept="image/*" capture="camera" id="file-upload">
                </span>
                <div id="spin"></div>

              <div class='btn btn-warning' ng-click='createEpisode()'> Create an Episode</div>
      </div>

The service for uploading to Firebase:

'use strict';

app.service('Uploader', ['$firebase', 'FIREBASE_TEST_URL', function($firebase, FIREBASE_TEST_URL) {

    var ref = new Firebase(FIREBASE_TEST_URL);

    var episodes = $firebase(ref);

    return {
        all: episodes,
        create: function(episode) {
            location.reload();
            //Add to firebase db
            return episodes.$add(episode);
        },
        delete: function(episodeId) { 
            location.reload();
            return episodes.$remove(episodeId);
        },
        update: function(episode) {
            location.reload();
            return episodes.$save(episode);
        }
    };
}]);

Controller that has the file handling for the image, etc.:

'use strict';

app.controller('UploadCtrl', ['$scope', 'Uploader', function ($scope, Uploader) {

$scope.episodes = Uploader.all;

$scope.createEpisode = function(){
    Uploader.create($scope.episode).then(function(data){
        $scope.episode.name = '';
        $scope.episode.title = '';
        $scope.episode.description = '';
        $scope.episode.time = '';
        $scope.episode.img1 = $scope.episodeImgData;
    });
};

$scope.deleteEpisode = function(episodeId){
    bootbox.confirm('Are you sure you want to delete this episode?', function(result) {
        if (result === true) { 
            Uploader.delete(episodeId).then(function(data){
                console.log('Episode successfully deleted!');
            });
        }
    });
};

$scope.updateEpisode = function(episode) {
    Uploader.update($scope.episode).then(function(data) {
        console.log(episode);
        console.log('Episode successfully updated.');
    });
};

$scope.selectEpisode = function(object) {
    $scope.selectedEpisode = object;
    setTimeout(function(){ $scope.$apply($scope.selectedEpisode = object); });
};

// ********************************************************************************** //
// START Image Upload: https://github.com/firebase/firepano/blob/gh-pages/firepano.js //
// REQUIRED: app/scripts/js/crypto.js in index.js
var spinner = new Spinner({color: '#ddd'});
$scope.episodeImgData = '../images/defaultplaceholder.png';

function handleFileSelectAdd(evt) {
  var f = evt.target.files[0];
  var reader = new FileReader();
  reader.onload = (function(theFile) {
    return function(e) {
        var filePayload = e.target.result;
        var hash = CryptoJS.SHA256(Math.random() + CryptoJS.SHA256(filePayload));

        $scope.episodeImgData = e.target.result; 

        document.getElementById('pano').src = $scope.episodeImgData; 
        console.log($scope.episodeImgData);
    };
  })(f);
  reader.readAsDataURL(f);
}

function handleFileSelectEdit(evt) {
  var f = evt.target.files[0];
  var reader = new FileReader();
  reader.onload = (function(theFile) {
    return function(e) {
        var filePayload = e.target.result;
        var hash = CryptoJS.SHA256(Math.random() + CryptoJS.SHA256(filePayload));

        $scpope.episodeImgData = e.target.result; 

        document.getElementById('pano2').src = $scope.episodeImgData; 
        $scope.selectedEpisode.img1 = $scope.episodeImgData;
        console.log($scope.episodeImgData);
    };
  })(f);
  reader.readAsDataURL(f);
}

$(function() {
    $('#spin').append(spinner);
    document.getElementById('file-upload').addEventListener('change', handleFileSelectAdd, false);  
    document.getElementById('file-upload2').addEventListener('change', handleFileSelectEdit, false); 

});
// END Image Upload: https://github.com/firebase/firepano/blob/gh-pages/firepano.js //
// ******************************************************************************** //
}]);

All the attributes in the form save to the DB except img1. When the update button is clicked, I thought I could just pass in episodeImgData to the object (img1 variable) to save, but it doesn't save anything at all (just the form variables tied to episode.name, etc.). What's the best way to do this? I'm using parts of the FirePano example (https://github.com/firebase/firepano/blob/gh-pages/firepano.js) for the image handling.

解决方案

Update (20160519): Firebase just released a new feature called Firebase Storage. This allows you to upload images and other non-JSON data to a dedicated storage service. We highly recommend that you use this for storing images, instead of storing them as base64 encoded data in the JSON database.

There were a lot of small problems with that code.

  • Since your episodes are an array, you can to create is with $asArray, otherwise it won't have a $add method: var episodes = $firebase(ref).$asArray();
  • You were calling location.reload() before sending the data to the server
  • Your file-upload handler wasn't triggering for me
  • There were dangling references to the spinner from firepano

I think that first two were the biggest. But it is hard to find that type of problem if you don't provide a minimal example that reproduces the problem. I did that for you now.

In the end, the code is not too big so I'll share it here:

var app = angular.module('myapp', ['firebase'])
.service('Uploader', function($firebase) {
  var ref = new Firebase('http://<yourfirebase>.firebaseio.com/');
  var episodes = $firebase(ref).$asArray();
  return {
    all: episodes,
    create: function(episode) {
      //Add to firebase db
      return episodes.$add(episode);
    }
  };
})
.controller('UploadCtrl', function ($scope, Uploader) {
  $scope.episodes = Uploader.all;
  $scope.createEpisode = function() {
    if ($scope.episodeImgData) {
      $scope.episode.img1 = $scope.episodeImgData;
    }
    Uploader.create($scope.episode);
  };
  $scope.handleFileSelectAdd = function(evt) {
    var f = evt.target.files[0];
    var reader = new FileReader();
    reader.onload = (function(theFile) {
      return function(e) {
        var filePayload = e.target.result;
        $scope.episodeImgData = e.target.result; 
        document.getElementById('pano').src = $scope.episodeImgData; 
      };
    })(f);
    reader.readAsDataURL(f);
  };
  document.getElementById('file-upload').addEventListener('change', $scope.handleFileSelectAdd, false);
});

The corresponding (body) HTML:

<body ng-app='myapp'>
  <div class="row modalDetail" ng-controller='UploadCtrl'>
    <h3>New Episode</h3>
    <table class="" ng-model='episode'>
      <tbody>
        <tr>
          <td class="labelField">Name</td>
          <td><input type='text' ng-model='episode.name'></td>
        </tr>
        <tr>
          <td class="labelField">Title</td>
          <td><input type='text' ng-model='episode.title'></td>
        </tr>
        <tr>
          <td class="labelField">Description</td>
          <td><input type='text' ng-model='episode.shortDescription'></td>
        </tr>
        <tr>
          <td class="labelField">Time</td>
          <td><input type='text' ng-model='episode.time'></td>
        </tr>
      </tbody>
    </table>

    <td class="labelField">Image</td>
    <span class="btn btn-default btn-file">
      <input type="file" accept="image/*" capture="camera" id="file-upload">
    </span>
    <div class='btn btn-warning' ng-click='createEpisode()'>Create an Episode</div>
    <br/>
    <img id="pano">

  </div>
</body>

This is a working demo if creating an episode with optional image data: http://jsbin.com/roriwu/7.

这篇关于将base64字符串传递给AngularJS中的对象属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆