- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我是使用仅提供 api 的 Rails 4 操作 angularjs 的新手。我尝试创建一个简单的 Angular 服务来上传文件。但是我使用 Paperclip 来管理文件,但我遇到了一些问题。
首先,我不明白如何正确收集输入文件。我已经看到很多插件或 fat 指令可以做到这一点。但我想要一个简单的指令来收集我的文件并放入我的 ng-model。
最后我想知道用 Base64 编码我的文件是否更有效?
我的 Rails Controller
class Api::EmployeesController < Api::BaseController
def create
employee = Employee.create(employee_params)
if employee.save
render json: employee
else
render :json => { :errors => employee.errors.full_messages }, :status => 406
end
end
def employee_params
params.require(:employee).permit(:first_name,:mobile_phone,:file)
end
end
我的 Angularjs 服务
angular.module('test').factory 'Employee', ($resource, $http) ->
class Employee
constructor: (errorHandler) ->
@service = $resource('/api/employees/:id',
{id: '@id'},
{update: {method: 'PATCH'}})
@errorHandler = errorHandler
create: (attrs, $scope) ->
new @service(employee: attrs).$save ((employee) ->
$scope.employees.push(employee)
$scope.success = true
$timeout (->
$scope.success = false
), 3000
), @errorHandler
我的 Angularjs Controller
angular.module('test').controller "EmployeesController", ($scope, $timeout, $routeParams, $location, Employee) ->
$scope.init = ->
@employeeService = new Employee(serverErrorHandler)
$scope.employees = @employeeService.all($scope)
$scope.createEmployee = (employee) ->
if $scope.employeeFirstName
@employeeService.create (
first_name: $scope.employeeFirstName
last_name: $scope.employeeLastName
promotion: $scope.employeePromotion
mobile_phone: $scope.employeeMobilePhone
nationality: $scope.employeeNationality
social_number: $scope.employeeSocialNumber
born_place: $scope.employeeBornPlace
employee_convention: $scope.employeeConvention
employee_type: $scope.employeeType
), $scope
else
$scope.error = "fields missing"
最佳答案
经过几天的故障排除和弄清楚这两种技术的工作原理(我对这两种技术都是新手 -.-),我设法让一些东西起作用。我不知道这是否是最好的方法,但它确实有效。如果有人有任何改进,我很乐意听到。
一般来说,我做了以下事情:
感觉真的很迂回,所以如果有其他方法可以做到这一点,我很想知道!
我正在使用 Rails 4 和 AngularJS、Paperclip 和 Restangular 的最新稳定版本。
相关代码如下:
Angularjs 指令
var baseUrl = 'http localhost:port'; // fill in as needed
angular.module('uploadFile', ['Restangular']) // using restangular is optional
.directive('uploadImage', function () {
return {
restrict: 'A',
link: function (scope, elem, attrs) {
var reader = new FileReader();
reader.onload = function (e) {
// retrieves the image data from the reader.readAsBinaryString method and stores as data
// calls the uploadImage method, which does a post or put request to server
scope.user.imageData = btoa(e.target.result);
scope.uploadImage(scope.user.imagePath);
// updates scope
scope.$apply();
};
// listens on change event
elem.on('change', function() {
console.log('entered change function');
var file = elem[0].files[0];
// gathers file data (filename and type) to send in json
scope.user.imageContent = file.type;
scope.user.imagePath = file.name;
// updates scope; not sure if this is needed here, I can not remember with the testing I did...and I do not quite understand the apply method that well, as I have read limited documentation on it.
scope.$apply();
// converts file to binary string
reader.readAsBinaryString(file);
});
},
// not sure where the restangular dependency is needed. This is in my code from troubleshooting scope issues before, it may not be needed in all locations. will have to reevaluate when I have time to clean up code.
// Restangular is a nice module for handling REST transactions in angular. It is certainly optional, but it was used in my project.
controller: ['$scope', 'Restangular', function($scope, Restangular){
$scope.uploadImage = function (path) {
// if updating user
if ($scope.user.id) {
// do put request
$scope.user.put().then( function (result) {
// create image link (rails returns the url location of the file; depending on your application config, you may not need baseurl)
$scope.userImageLink = baseUrl + result.image_url;
}, function (error) {
console.log('errors', JSON.stringify(errors));
});
} else {
// if user does not exist, create user with image
Restangular.all('users')
.post({user: $scope.user})
.then(function (response) {
console.log('Success!!!');
}, function(error) {
console.log('errors', JSON.stringify(errors));
});
}
};
}]
};
});
带指令的 Angular 文件
<input type="file" id="fileUpload" ng-show="false" upload-image />
<img ng-src="{{userImageLink}}" ng-click="openFileWindow()" ng-class="{ hidden: !userImageLink}" >
<div class="drop-box" ng-click="openFileWindow()" ng-class=" {hidden: userImageLink}">
Click to add an image.
</div>
这会创建一个隐藏文件输入。 userImageLink
在 Controller 中设置,openFileWindow()
方法也是如此。如果用户图片存在,它会显示,否则会显示一个空白的 div,告诉用户点击上传图片。
在负责上述html代码的 Controller 中,我有以下方法:
// triggers click event for input file, causing the file selection window to open
$scope.openFileWindow = function () {
angular.element( document.querySelector( '#fileUpload' ) ).trigger('click');
console.log('triggering click');
};
Rails 端
在用户模型的 Controller 中,我有以下方法:
# set user params
before_action :user_params, only: [:show, :create, :update, :destroy]
def create
# if there is an image, process image before save
if params[:imageData]
decode_image
end
@user = User.new(@up)
if @user.save
render json: @user
else
render json: @user.errors, status: :unprocessable_entity
Rails.logger.info @user.errors
end
end
def update
# if there is an image, process image before save
if params[:imageData]
decode_image
end
if @user.update(@up)
render json: @user
else
render json: @user.errors, status: :unprocessable_entity
end
end
private
def user_params
@up = params.permit(:userIcon, :whateverElseIsPermittedForYourModel)
end
def decode_image
# decode base64 string
Rails.logger.info 'decoding now'
decoded_data = Base64.decode64(params[:imageData]) # json parameter set in directive scope
# create 'file' understandable by Paperclip
data = StringIO.new(decoded_data)
data.class_eval do
attr_accessor :content_type, :original_filename
end
# set file properties
data.content_type = params[:imageContent] # json parameter set in directive scope
data.original_filename = params[:imagePath] # json parameter set in directive scope
# update hash, I had to set @up to persist the hash so I can pass it for saving
# since set_params returns a new hash everytime it is called (and must be used to explicitly list which params are allowed otherwise it throws an exception)
@up[:userIcon] = data # user Icon is the model attribute that i defined as an attachment using paperclip generator
end
user.rb 文件应该是这样的:
### image validation functions
has_attached_file :userIcon, styles: {thumb: "100x100#"}
#validates :userIcon, :attachment_presence => true
validates_attachment :userIcon, :content_type => { :content_type => ["image/jpg", "image/gif", "image/png"] }
validates_attachment_file_name :userIcon, :matches => [/png\Z/, /jpe?g\Z/]
我认为这是相关的一切。希望这可以帮助。当我有时间的时候,我可能会把这个贴在其他地方更清楚一点。
关于javascript - Rails 4 Angularjs Paperclip 如何上传文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20521366/
sanitize 是什么意思在 Rails 中是什么意思? 我正在阅读 CanCanCan 的文档.它说: When using strong_parameters or Rails 4+, you
在过去的几个月里,我感觉自己对 Ruby on Rails (RoR) 开发的了解达到了极限。我为大/小客户和 friend /爱好项目开发了大大小小的应用程序。我知道如何开发这些应用程序,但开始感觉
我昨天参加了一个关于扩展 Rails 的聚会,其中一个主题是 Hexagonal Rails。然而,我只做了一年的 Rails,对 MVC 结构非常满意(也许太舒服了),所以我不太了解适配器和消息队列
我使用多个 Rails 应用程序,一些在 Rails 3.2/Ruby 2.0 上,一些在 Rails 2.3/Ruby 1.8.7 上。 他们的共同点是,随着他们的成长和添加更多的依赖项/ gem
这个问题在这里已经有了答案: Using Rails-UJS in JS modules (Rails 6 with webpacker) (5 个答案) 关闭 3 年前。 我正在尝试使用 UJS
我正在开发一个当前使用 Rails 1.2 的 Rails 应用程序,所以我现在离最新的稳定版本(Rails 2.3)还有很长的路要走。 我应该如何进行迁移到更新版本的 Rails 的过程? 我应该一
尝试按照 Ryan Bates Backbone.js 教程构建抽奖应用程序,但我已经遇到了第一段代码的问题。在 application.js 的 init 函数中,他初始化了 Raffler 路由的
我正在使用 Rails 3.2 并且我有一个数据库表,我想在其中找到符合以下条件的所有行: a = true and b = true and ( 0 true, :b =>
我有一个用户类和一个联系人,其中联系人是用户的子类。这两个类都存储在用户表中。 我的联系人可能有也可能没有电子邮件地址,而我的用户需要一个电子邮件地址(我的用户模型定义中有 validates_pre
我正在编写一个教程,我在其中演示了一些 rails 命令。在我的机器上 rails和 script/rails两者都同样有效。有“首选”形式吗?两者中哪一个更普遍? 最佳答案 当您运行 rails 时
我正在寻找有关通过我的应用程序前进的最佳方式的建议,这是我首次开始集成Elasticsearch。我是一名初学者,但是热衷于深入研究,以便原谅任何明显的错误! 我遵循了http://www.sitep
我刚刚用 Rails new 启动了一个新的 Rails 应用程序,将默认数据库设置更改为 PostgresSQL。我用 bin/rails s 启动服务器,结果很奇怪 2016-04-21 05:0
我收到一个参数并希望它是这样的字符串: "abc,efg" 或者像这样的数组 ["abc","efg"] 在第一种情况下,我想将它转换成一个数组,什么是好的方法? 这是我的想法 if params[:
我刚刚用 Rails new 启动了一个新的 Rails 应用程序,将默认数据库设置更改为 PostgresSQL。我用 bin/rails s 启动服务器,结果很奇怪 2016-04-21 05:0
我收到一个参数并希望它是这样的字符串: "abc,efg" 或者像这样的数组 ["abc","efg"] 在第一种情况下,我想将它转换成一个数组,什么是好的方法? 这是我的想法 if params[:
我有 Rails 4,这是我的默认版本(我仍然希望它是)。但我不想在我的电脑上添加 rails 3.2。在以下命令中:gem install rails -v 3.2.16 我有这个警告: railt
您好,我想使用 Sheevaplug 构建一个“Rails Brick”来自 Marvell(操作系统是开箱即用的 Ubuntu,但您可以在其上安装其他发行版)。它将成为家庭服务器和静音、低成本(99
我需要能够从 Rails 控制台发送我的 Rails 应用程序的 Postgres 数据库中所有未接受的邀请。 (我有一个名为 Invitations 的表,其中包含一个名为 accepted 的 b
validate :cannot_modify_if_locked, on: :update def cannot_modify_if_locked if self.locked erro
我正在学习教程(学习 Rails 播客),需要更改以下路由语法,以便它与 Rails 3.0 兼容。谁能帮忙? map.view_page ':name', :controller => 'viewe
我是一名优秀的程序员,十分优秀!