2015-12-23 10 views
10

Я загружаю изображение с угловым, например.Загрузка изображений ng-src с помощью webpack

<img ng-src="{{::path-to-image}}"/> 

Когда я связать мое приложение с WebPack URL-адрес изображения разрешен во время выполнения, таким образом, не в комплекте погрузчиками WebPack в.

Это загрузчик изображений Я использую:

{ 
    test: /\.(jpe?g|png|gif|svg)$/i, 
    loader: 'url?limit=8192!img' 
    } 

Как WebPack может связать эти образы решены во время выполнения?

ответ

16

Потому что я также нуждался в такой функциональности и нашел, что первоначальный ответ был далек от идеального решения. Я закончил тем, что понял это самостоятельно.

Написать функцию в контроллере:

$scope.loadImage = function(image) { 
    return require('/images/' + image); 
}; 

и использовать его в нг-Src:

<img ng-src="{{loadImage('myImage')}}" /> 

После этого сделать динамический требует работы вы можете использовать context.

Например: https://github.com/webpack/webpack/tree/master/examples/require.context#examplejs

+0

Умное решение! Спасибо за обмен. –

+1

Отлично работает для меня. Еще раз спасибо –

+0

Нет проблем. :)) –

9

Если вам нужен путь изображения, который программно сгенерирован, это означает, что у вас есть логика, ожидающая, что это изображение будет существовать. Другими словами, вы должны рассматривать этот образ как зависимость от этой части логики, поэтому вам нужно явно ее требовать.

В коде JS (например: контроллер)

this.imageUrl = require('path-to-image' + someDynamicValue + '.jpg'); 

В шаблоне:

<img ng-src="{{::myCtrl.imageUrl}}"/> 

Webpack достаточно умен, чтобы понять динамический require заявление и связать изображения, которые будут соответствовать, что выражение , Посмотрите документацию для получения более подробной информации: https://webpack.github.io/docs/context.html)

+1

Ваше предложение распространяется вид логики в контроллере, который был раньше не догадывались, если и как представление (файл html) предоставило данные. Он больше похож на ограничение WebPack для меня, то есть он не может обрабатывать ресурсы, которые разрешены во время выполнения. Думаю, я вернусь к глотку для копирования моих статических активов в папку dist /. Благодарю. –

+0

Действительно, и у меня смешанные чувства по этому поводу. Но на самом деле Webpack может справиться с этим (через вызов require(), как я показал его). Это скорее ограничение html-loader, так как оно не учитывает угловое выражение в атрибуте src (или ng-src). – gonzoyumo

+0

Еще одно слово: полагаясь на внешний инструмент для копирования/создания активов, вы скрываете зависимость между вашим кодом (html) и изображением. Для меня это похоже на использование $ в глобальной области (и ожидая, что оно уже определено в этой точке) вместо явно требующего его с помощью 'var $ = require ('jquery');' Мы не привыкли думать так: такие типы (шрифты, изображения, стили), но в конце концов, для чего нужны css и другие загрузчики файлов. – gonzoyumo

2

Я создал uiImage директиву, которая requires изображения.

function uiImage() { 
    return { 
     restrict: 'A', 
     link: function(scope, element, attr) { 
     var src = attr.uiImage || attr.src; 

     function loadImage(image) { 
      return require(`Images/${image}`); 
     } 

     // required for webpack to pick up image 
     element.attr('src', loadImage(src)); 
     } 
    }; 
    } 

    uiImage.$inject = []; 
    export default uiImage; 

Использование:

<img ui-image='myimage.png' /> 

webpack.config.js

У меня есть Webpack решить Images, который указывает на расположение всех моих изображений.

resolve: { 
    alias: { 
    'Images': path.join(config.appDir, '/images') 
    } 
} 
+0

Благодарим вас за решение, отлично работает! – matox

0

мне нужно динамически разрешить изображения во время выполнения с хешами, генерируемого WebPack, например, imgA.bd79a5ba.png.

{ 
    test: /\.png$/, 
    loader: 'file-loader?name=images/[name].[hash].[ext]', 
} 

Я в конечном итоге создать модуль для псевдонима и требует изображения:

let map = { 
    'imgA': require('./images/imgA.png'), 
    'imgB': require('./images/imgB.png'), 
    'imgC': require('./images/imgC.png') 
} 

Это создает карту:

{ 
    'imgA': imgA.bd79a5ba.png, 
    'imgB': imgB.e51f66a2.png, 
    'imgC': imgC.d84ae37c.png 
} 

В моем компоненте я решил URL-адрес с карты:

self.link = function link(scope) { 
    scope.imageUrl = function(name) { 
    function return map[name]; 
    } 
}; 

Это был для загрузки изображения:

<img ng-src="{{ imageUrl('imgA') }}"> 

Вышеприведенное упрощено. Я нашел, что это полезно для создания модуля для карты:

export default { 
    'imgA': require('./images/imgA.png'), 
    'imgB': require('./images/imgB.png'), 
    'imgC': require('./images/imgC.png') 
} 

затем импортировать его в компонент модуля:

import urlMap from './imageUrlMap' 
console.log(urlMap.imgA) 

> imgA.bd79a5ba.png 
Смежные вопросы