Angular Directives观看外部模型

Kri*_*son 7 javascript angularjs angularjs-directive

在学习Angular时,我正在创建一个可以缩放的简单图库.我最初的实现使用了一个简单的ng-repeat,但我很快发现,根据画廊的缩放,我想改变像url源(从小到大拇指)的东西,可能还有css上的字幕等.

<div class="photoHolder" ng-repeat="photo in photos | filter:{caption:query} | orderBy:orderProp" ng-attr-style="transition: .3s ease; width: {{thumbWidth}}px; height: {{thumbWidth}}px;">
    <div class="photoClass" data-id="{{photo.id}}" ng-attr-style="background-image:url({{zoomSize < 5 ? photo.thumb_url : photo.medium_url}})"></div>
    <div class="caption">{{photo.caption}}</div>
    <div class="caption">{{photo.date}}</div>
</div>
Run Code Online (Sandbox Code Playgroud)

所以,我改用了一个更清洁的指令:

<gal-photo class="photoHolder" ng-repeat="photo in photos | filter:{caption:query} | orderBy:orderProp"/>  
Run Code Online (Sandbox Code Playgroud)

但是我可以获得指令元素来响应缩放更改的唯一方法是将指针添加到元素链接内的缩放:

link: function(scope, element, attrs) {
    var image = new Image();
    scope.photo.url = scope.zoomSize < 5 ? scope.photo.thumb_url : scope.photo.medium_url;
    scope.$watch('thumbWidth', function() {
           scope.photo.url = scope.zoomSize < 5 ? scope.photo.thumb_url : scope.photo.medium_url;
        element.attr('style',  'transition: .3s; width: ' + scope.thumbWidth + 'px; height: ' + scope.thumbWidth + 'px;');
    });
}
Run Code Online (Sandbox Code Playgroud)

我知道你不应该滥用手表,我担心的是,在画廊中有500个元素,你要做500块手表.但我没有找到在重复指令中响应外部输入的指导.两个画廊似乎表现差不多,但我想知道我是否做错了?这是原始画廊的小提琴和指令版的小提琴.

Bey*_*ers 6

您的用例是$ scope事件的良好候选者.在你的控制器内有一块手表:

$scope.$watch('thumbWidth', function() {
    $scope.$broadcast('thumbWidthChange');
});
Run Code Online (Sandbox Code Playgroud)

然后在你的指令中注册这个事件的监听器:

scope.$on('thumbWidthChange', function(){
    scope.photo.url = scope.zoomSize < 5 ? scope.photo.thumb_url : scope.photo.medium_url;
    element.attr('style',  'transition: .3s; width: ' + scope.thumbWidth + 'px; height: ' + scope.thumbWidth + 'px;');
});
Run Code Online (Sandbox Code Playgroud)

范围事件侦听器仅在其事件被触发时被调用,因此这应该限制监视列表并优化性能.

这是一个基于您使用事件方法的示例的更新小提琴:http://jsfiddle.net/dv7fy/1/

作为旁注,Angular手表的性能比大多数人想象的要好,看看这个例子(仍然在Angular 1.0.3上,在最新版本上应该更好):http://jsfiddle.net/mhevery/cXMPJ/11 /


ana*_*ker 3

我认为拜尔斯说得对,手表实际上非常高效。

不过,您可以通过对整个图像库使用父指令来使用单个手表来执行此操作:

myApp.directive('imageGallery', function() {
return {
    restrict: 'A',
    controller: function($scope, $element, $attrs) {
        function updatePhotos() {
            $element.children().attr('style',  'transition: .3s; width: ' + $scope.thumbWidth + 'px; height: ' + $scope.thumbWidth + 'px;');
            $scope.photos.forEach(function(photo){
                photo.url = $scope.zoomSize < 5 ? photo.thumb_url : photo.medium_url;
            });
        };

        this.updatePhotos = updatePhotos;
    },
    link: function(scope, element, attrs, ctrl) {
        scope.$watch('thumbWidth', function() {   
            ctrl.updatePhotos();
        });
        ctrl.updatePhotos();
    }
}
});
Run Code Online (Sandbox Code Playgroud)

(这里有完整的小提琴)

请注意,我已将中央更新逻辑放入controller而不是link函数中。这在这里并不是绝对必要的,但它在将来可能有用,因为该控制器对象对子galPhoto指令是可见的。(请参阅小提琴中的两个“NOTE”注释。)