2014-05-23 21 views
1

我使用AngularJS这些宝石的Rails 4应用:的Rails在AngularJS指令图片资源和模板

  • 宝石 'angularjs护栏'
  • 宝石 '角轨模板'
  • 宝石“ asset_sync”

它有这样的一个模板的伟大工程:

<img ng-controller='LikePostController' 
     ng-dblclick='like(post);' 
     ng-src='{{post.photo.standard}}' 
     class='lazy post_photo pt_animate_heart' 
     id='post_{{post.id}}_image' 
    /> 

图像正确呈现。但在我的其他js

petto.directive('ptAnimateHeart', ['Helper', function(Helper){ 
    linkFunc = function(scope, element, attributes) { 
     $heartIcon = $("#heart_icon"); 

     if($heartIcon.length == 0) { 
     $heartIcon = $("<img id='heart_icon' src='/assets/feed.icon.heart.png' alt='Like' /> "); 
     $(document.body).append($heartIcon); 
     } 

     element.on('dblclick', function(event){ 
     $animateObj = $(this); 
     Helper.animateHeart($animateObj); 
     }); 
    } 
    return { 
     restrict: 'C', 
     link: linkFunc 
    } 

    }]) 

我得到'assets/feed.icon.heart.png'从浏览器控制台未找到错误。我有位于app/assets/feed.icon.heart.png下的feed.icon.heart.png。

ps:忘记提及我使用资产同步宝石在亚马逊s3托管资产。该图像在开发中运行良好,但未在生产中运行。

回答

11

硬编码资产链接仅适用于开发,因为在生产过程中资产会被预编译。这意味着,除其他事项外,从文件名更改:

my_image.png

弄成这个样子(它增加了独特的MD5哈希):

"my_image-231a680f23887d9dd70710ea5efd3c62.png"

试试这个:

将javascript文件的扩展名更改为:yourjsfile.js.erb

而且链接:

$heartIcon = $("<img id='heart_icon' src='<%= image-url("feed.icon.heart.png") %>' alt='Like' /> ");

为了更好地理解The Asset Pipeline — Ruby on Rails Guides

+0

你会怎么做这个循环内? image_url在JavaScript内插中不起作用。 –

+0

您可以使用坤宝石:http://railscasts.com/episodes/324-passing-data-to-javascript – crispychicken

+2

它帮助了我。唯一需要提及的是:我需要使用'image_url'而不是'imge-url',我使用的是Rails 4.2.6 – olyv

3

你可以在你的助手,如某处定义如下方法在app/helpers/application_helper.rb

def list_image_assets(dir_name) 
    path = File.expand_path("../../../app/assets/images/#{dir_name}", __FILE__) 
    full_paths = Dir.glob "#{path}/**.*" 
    assets_map = {} 
    full_paths.each do |p| 
    original_name = File.basename p 
    asset_path = asset_path p[p.index("#{dir_name}")..-1] 
    assets_map[original_name] = asset_path 
    end 
    assets_map.to_json 
end 

一个可以修改你希望的任何资产,而不是仅仅定位于app/assets/images子目录如本例中的那些工作的方法。该方法将返回包含所有原始资产名称作为关键字及其“编译”名称作为值的映射。

(在这种情况下通常不推荐,但适当时)返回可以被传递到任何角度控制器经由ng-init的地图:

<div ng-controller="NoController" ng-init="assets='<%=list_image_assets "images_dir_name"%>'"></div> 

为了使资产在角真正可用,在定义新$scope valiable控制器:

$scope.$watch('assets', function(value) { 
    if (value) { 
    $scope.assets = JSON.parse(value); 
    } 
}); 

$scope到这一点,这是可能的资产使用的名称像往常一样,在如ng-src指令,并且这在预编译过程之后不会制动。

<img ng-src={{::assets['my_image.png']}}/> 
+0

我喜欢这个解决方案,这是唯一一个不使用'.erb'而且不把图像直接放置进入“公共”目录。但它仍然看起来太痛苦了 –

+0

好的解决方案在于:A)它迫使你理解一些关于底层资产编译过程和B)如果你只需要传入一小部分资产。当你发现自己一直在做这件事时,使用'gon'宝石可能会有意义。 –

0

只需做到以下几点:

app.run(function($rootScope,$location){ 
$rootScope.auth_url = "http://localhost:3000" 
$rootScope.image_url = $rootScope.auth_url + "/uploads/user/image/" 
}); 

在控制器注入dependency$rootScope 和意见

<img ng-src="{{user.image.url}}" width="100px" height="100px"> 

注:它的工作在Rails的API伟大的,它假定你” ve用户对象可用,以便它可以在/uploads/image/目录中指定正确的图像