簡體   English   中英

Angular指令:重新縮放圖像,在ngSrc更改時更新

[英]Angular directive: rescale images, update when ngSrc changes

我有一個Angular指令,當加載事件被觸發時,它當前正在執行其工作:

.directive("testDir", [
    function() {
        return {
            link: function(scope, elm, attrs) {
                    ...
                return elm.one("load", function() {
                    return ...
                });
            }
        };
    }
]);

該指令被添加到<img>標簽,該標簽源自ng-src 該指令應縮小圖像尺寸,以在移動設備上實現更好的性能。

現在我的問題是:我希望指令函數不是在.one()時觸發,而是在每次ng-src的鏈接變量(通過{{}} )改變后才觸發。 我怎么能知道呢?

我希望該指令盡可能獨立,因此我希望它中沒有底層控制器的顯式變量名。

JavaScript的:

.directive(
  "testDir", [
    function() {
      return {
        scope: {
          imgSrc: '='
        },

        link: function(scope, elm, attrs) {
          scope.$watch(
            'imgSrc', function(newVal) {
              // here you can update whatever you want
            }
          );
        }
      };
    }
  ]
);

HTML:

<img ng-src="{{scopeModel}}" test-dir img-src="scopeModel"/>

編輯2

好了,這里是畫布而不是CSS。 您應該知道。 因為使用了兩個參數-percent和url,所以我將其設置為完整元素指令:

的script.js

var myApp = angular.module('myApp', []);

myApp.controller("MyCtrl", function($scope) {
  $scope.i = 0;
  $scope.urls = ["_71832498_71825880.jpg",
    "0411_hubble_970-630x420.jpg"
  ]
  $scope.changePic = function() {
    if ($scope.i == 0) {
      $scope.i = 1;
      return;
    }
    if ($scope.i == 1) {
      $scope.i = 0;
      return;
    }
  }
})

myApp.directive("scaleImage", [
  '$http',
  function($http) {
    return {
      restrict: 'E',
      scope: {
        percent: '&',
        url: '&',
      },
      template: '<img ng-src="{{ src }}" />',
      link: function (scope, elm, attrs) {
        var img;

        scope.$watch(function () {
          // Because we're returning an object we need to deep watch.  Do this sparingly.
          // Doing this on large arrays or objects can be ill-performant, but I think this
          // is fine here.
          return {
            percent: scope.percent(),
            url: scope.url(),
          }
        }, function (value) {
          if (!value.percent || !value.url) {
            return;
          }

          // Remove the old one, if any.  Should hopefully fix any memory leaks related to
          // creating an element.
          if (img) {
              img.remove();
          }

          img = angular.element('<img style="display: none" src="' + value.url + '">');
          elm.append(img);

          // This will give it enough time to load the image and render the element 
          // so that it has a height and whatnot; may not be needed.  Was needed in plunker
          // at some point; can't tell on localhost, doesn't seem to hurt.
          $http.get(value.url).then(function () {
            var canvas, ctx, neededHeight, neededWidth;
            neededHeight = img[0].naturalHeight * value.percent / 100;
            neededWidth = img[0].naturalWidth * value.percent / 100;
            canvas = document.createElement("canvas");
            canvas.width = neededWidth;
            canvas.height = neededHeight;
            ctx = canvas.getContext("2d");
            ctx.drawImage(img[0], 0, 0, neededWidth, neededHeight);
            scope.src = canvas.toDataURL("image/jpeg");
          });

        }, true); // true to deep watch
      }
    };
  }
]);

的index.html

<!DOCTYPE html>
<html>

<head>
  <script src="angular.js"></script>
  <script src="script.js"></script>
</head>

<body>
  <div ng-app="myApp" ng-controller="MyCtrl">
    <input type="number" ng-model="percent" ng-init="percent = 4">
    <scale-image url="urls[i]" percent="percent"></scale-image>
    <button ng-click="changePic()">Change Picture</button>
  </div>
</body>

</html>

編輯

http://plnkr.co/edit/MoEsJPRwR1nFOhRKd37q?p=preview

myApp.directive("scaleImage", [
  function() {
    return {
      link: function(scope, elm, attrs) {
        attrs.$observe('scaleImage', function (value) {
          elm.css('width', value + '%');
          elm.css('height', value + '%');
        });
      }
    };
  }
]);

讓我知道這是否無效。


你可以做:

attrs.$observe('src' /* might be `ngSrc` */, function (value) { /* this is executed when the interpolated value of src changes */ });

如果那不起作用,您可以設置一個塞子或小提琴嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM