2014-05-23 34 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/目錄中指定正確的圖像