使用带有<img/>标记的CDN

时间:2016-04-13 16:22:53

标签: javascript angularjs cdn content-delivery-network

我刚刚添加了CDN服务,以加快我的网站加载速度。 我对使用<img>标记提取的照片有疑问。

我有很多这样的案例:

// userProfile.thumbnailPhotoSrc = some/relative/path.png    
ng-src="{{userProfile.thumbnailPhotoSrc}}"

(我使用AngularJS)。

启动时,我有一个脚本将CDN端点保存到window.cdn变量。 如果脚本确定没有可用的端点:

window.cdn = '';

所以我希望能够做到这样的事情:

ng-src="window.cdn + {{userProfile.thumbnailPhotoSrc}"

但这是不可能的,因为window.cdn未被评估。但这都不起作用:

ng-src="{{window.cdn + userProfile.thumbnailPhotoSrc}"

因为我只能访问$scope下的{{}}个媒体资源。 我无法将CDN端点保存到$scope,因为每个控制器都存在$scope(我有很多,这是不可维护的。)

我想到的最后一件事,希望ng-src允许 - 正在添加一个在任何ng-src属性上运行的转换函数,但我找不到如何做到这一点。

你建议我做什么?请记住,我希望网站从CDN获取照片,并在CDN出现故障时回退到原始服务器(获取相对路径)。我怎样才能获得这种行为?

由于

2 个答案:

答案 0 :(得分:4)

您可以在Angular中创建custom filter

然后您将在模板中使用:

ng-src="{{userProfile.thumbnailPhotoSrc | cdn}"

您可以将$window服务作为依赖项添加到过滤器服务中,这样您就不必从全局对象中提取它,也可以测试过滤器。

答案 1 :(得分:1)

如果您要更新所有<img>代码的src。您可以创建一个指令:

angular.module('imageCdnSrc', [])
.directive('img',['$interpolate', function($interpolate) {
    return {
    restrict: 'E',
    scope: false,
    compile: function(element, attrs) {
      var ngSrc = attrs.ngSrc;
      delete attrs.ngSrc; // prevent ngSrc directive to trigger

      return function($scope,element,attrs) {
        var ngSrcVal = $interpolate(ngSrc)($scope); //returns the string value of ngSrc

        /* Add Logic Below to decide what to do */
        if(window.cdn && ngSrcVal && ngSrcVal.length>0){
          attrs.ngSrc = window.cdn + ngSrcVal;
          /* if image fails to load with cdn, load the default */
          element.one('error', function() {
            angular.element(this).attr("src", ngSrcVal);
          });
        }
        else{
          attrs.ngSrc = ngSrcVal;
        }
      };      
    }
  };
}]);