Javascript $timeout是避免AngularJS指令中jQuery插件呈现问题的唯一/推荐方法吗?

Javascript $timeout是避免AngularJS指令中jQuery插件呈现问题的唯一/推荐方法吗?,javascript,jquery,angularjs,angularjs-directive,Javascript,Jquery,Angularjs,Angularjs Directive,我正在将一个jQuery webapp移植到AngularJS(我的答案似乎很接近,但可能会消除您对$timeout的需要。尝试制作另一个指令并将其附加到li元素。类似于以下伪代码: angular.module('myApp').directive('pdfClick', function() { return { restrict: 'A', link: function(scope, element, attrs) { $el

我正在将一个jQuery webapp移植到AngularJS(我的答案似乎很接近,但可能会消除您对$timeout的需要。尝试制作另一个指令并将其附加到
li
元素。类似于以下伪代码:

angular.module('myApp').directive('pdfClick', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            $element.bxSlider().delegate('a', 'click', pdfClicked);
        }
    }
});

<li class="doc-thumbnail" ng-repeat="doc in docs" pdfClick>
angular.module('myApp')。指令('pdfClick',function(){
返回{
限制:“A”,
链接:函数(范围、元素、属性){
$element.bxSlider().delegate('a','click',pdfClicked);
}
}
});

  • 它应该将click事件附加到由ng repeat生成的每个列表项的锚点。

    我的答案似乎是正确的,但可能会消除您对$timeout的需要。尝试制作另一个指令并将其附加到
    li
    元素。类似于以下伪代码:

    angular.module('myApp').directive('pdfClick', function() {
        return {
            restrict: 'A',
            link: function(scope, element, attrs) {
                $element.bxSlider().delegate('a', 'click', pdfClicked);
            }
        }
    });
    
    <li class="doc-thumbnail" ng-repeat="doc in docs" pdfClick>
    
    angular.module('myApp')。指令('pdfClick',function(){
    返回{
    限制:“A”,
    链接:函数(范围、元素、属性){
    $element.bxSlider().delegate('a','click',pdfClicked);
    }
    }
    });
    

  • 它应该将单击事件附加到由ng repeat生成的每个列表项的锚点。

    您的问题是赛车条件问题,因此您不能只删除
    $timeout
    。发生的情况大致如下:

  • Angular编译这两个元素
  • 角度链接您
    bx滑块
    元素
  • bx滑块
    查找
  • 元素(此时无)并创建列表
  • 角度链接
    ng repeat
    并构建
  • 列表并解析绑定
  • 因此,为了解决赛车条件的第一个方面(仅在所有
  • 就绪后构建组件),您应该在
    bxSlider
    指令中公开
    update
    方法,并使用以下命令创建一个子指令,该子指令将调用
    bxSlider
    控制器中的
    update
    函数:

    指令('bxSlider',函数(){
    变量BX\u滑块\u选项={
    米斯利德斯:2,
    maxSlides:7,
    滑动宽度:120
    };
    返回{
    限制:“A”,
    require:'bxSlider',
    优先级:0,
    控制器:函数(){},
    链接:函数(范围、元素、属性、ctrl){
    var滑块;
    ctrl.update=函数(){
    slider&&slider.destroySlider();
    slider=element.bxSlider(BX\u slider\u选项);
    };
    }
    }
    }])
    .directive('bxSliderItem',函数($timeout){
    返回{
    要求:“^bxSlider”,
    链接:函数(范围、elm、attr、bxSliderCtrl){
    如果(范围$last){
    bxSliderCtrl.update();
    }
    }
    }
    })
    
    此解决方案甚至可以向模型中添加新的iTen,因为每次您有一个新的
    $last
    项时,bxSlider都会被构建。但同样,您会遇到另一种竞赛条件。在步骤3期间,滑块组件将最后一个元素复制到cr,以便在第一个元素之前显示它给人一种“连续性”的印象(看看小提琴来理解我的意思)。所以现在你的流程是这样的:

  • Angular编译这两个元素
  • 角度链接您
    bx滑块
    元素
  • 角度链接
    ng repeat
    并构建
  • 列表
  • 您的代码调用父
    update
    函数,该函数调用您的组件构建过程,复制最后一个元素
  • Angular解析绑定
  • 现在,你的问题是,滑块所做的复制只携带元素的模板,因为Angular还没有解决它的绑定问题。所以,每当你循环列表时,你会看到一个断开的内容。要解决它,仅仅1毫秒就足够了,因为你要交换步骤4和5的顺序,作为Angular binding Resolutionn与
    $digest
    循环发生在同一堆栈中,因此您应该没有问题:

    指令('bxSliderItem',函数($timeout){
    返回{
    要求:“^bxSlider”,
    链接:函数(范围、elm、attr、bxSliderCtrl){
    如果(范围$last){
    $timeout(bxSliderCtrl.update,1);
    }
    }
    }
    })
    
    但是您有一个新的问题,因为滑块复制了边界元素,AngularJs digest cycle无法查看这些复制,所以您失去了在这些组件中绑定模型的能力

    在所有这些之后,我建议你使用

    因此,总结如下:

  • 您可以在解决方案中使用1毫秒的延迟,因为角度摘要周期是同步的;-但是您失去了向列表中添加新项目的功能
  • 您也可以使用
    $scope.$last
    技巧使用
    $timeout
    但是您丢失了角度绑定,如果此组件有任何实例(选中,悬停),您将遇到问题
  • 您可以使用已经编写好的解决方案(就像我建议的那样)
  • 您可以编写自己的AngularJs本机解决方案

  • 您的问题是赛车条件问题,因此您不能仅删除
    $timeout
    。发生的情况大致如下:

  • Angular编译这两个元素
  • 角度链接您
    bx滑块
    元素
  • bx滑块
    查找
  • 元素(此时无)并创建列表
  • 角度链接
    ng repeat
    并构建
  • 列表并解析绑定
  • 因此,为了解决赛车条件的第一个方面(仅在所有
  • 准备就绪后构建组件),您应该在
    bxSlider
    指令中公开
    update
    方法
    angular.module('myApp')
        .directive('docListWrapper', ['$timeout', function ($timeout) {
            return {
                restrict: 'C',
                templateUrl: 'partials/doc-list-wrapper.html',
                scope: { docs: '=docs'},
                link: function (scope, element, attrs) {
    
                    $timeout(function () { // <-------------------- $timeout
                        element
                            .children('.doc-list')
                            .not('.ng-hide')
                            .bxSlider();
                    }, 10);
                }
            };
        }]);
    
    angular.module('myApp')
        .directive('docListWrapper', [function () {
            return {
                restrict: 'C',
                templateUrl: 'partials/doc-list-wrapper.html',
                scope: { docs: '=docs'},
                link: function (scope, element, attrs) {
    
                    scope.$watch('docs', function () { // <---------- $watch
                        element
                            .children('.doc-list')
                            .not('.ng-hide')
                            .bxSlider();
                    });
                }
            };
        }]);