在动态指令中初始化替换元素上的插件

时间:2013-09-29 16:47:52

标签: angularjs angularjs-directive

我正在尝试在指令中的元素上初始化Swipe.js。我之前有过这个工作,但是我正在修改我的指令,根据轮播类型动态加载模板,然后编译它,然后初始化插件。这是我的指示:

directive('carousel', ['$compile', '$http', '$templateCache', function($compile, $http, $templateCache) {
    var templateMap = { 
        default:    'default.html',
        products:   'partials/carousel/products.html'
    }, loader;

    return {
        restrict: 'E',
        replace: true,
        scope: {
            type: '@',
            slides: '=' 
        },  

        compile: function(tElement, tAttrs) {
            var template = templateMap[tAttrs.type];
            loader = $http.get(template, {cache: false}).success(function(html) {
                tElement.html(html);
            }); 

            return function(scope, element, attrs) {
                loader.then(function() {
                    scope.$watch('slides', function(slides) {
                        if(slides) {
                            console.log(element);
                            template = angular.element($compile(tElement.html())(scope));
                            element.replaceWith(template);
                            console.log(element);
                        }   
                    }); 
                }); 
            };  
        }   
    }   
}])

当我console.log(element)时,它会按照我的预期记录<carousel></carousel>元素。当我执行replaceWith(),然后console.log(element)时,我希望它显示已加载的新替换元素,但它仍会记录轮播元素。

如果它正在替换,正如我期望的那样,我会对新元素进行Swipe(element),但显然这不起作用。

任何提示?

1 个答案:

答案 0 :(得分:0)

.replaceWith()会返回对元素的引用,这就是您的第二个console.log()仍在打印<carousel>的原因。文档说明:

  

与大多数jQuery方法一样,.replaceWith()方法返回   jQuery对象,以便可以将其他方法链接到它上面。然而,   必须注意返回原始 jQuery对象。这个   object指的是从DOM中删除的元素,而不是   已取代它的新元素。

解决这个问题的方法是使用.replaceAll(),这在很大程度上是相同的,但顺序相反。 .replaceAll()返回对 new DOM元素的引用,这可以解决您的问题。

在装载程序回调中尝试此操作:

if(slides) {
    console.log(element);
    template = angular.element($compile(tElement.html())(scope));
    element.after(template);

    console.log(element);

    new Swipe(element[0], { /* ... */ });
} 

您可以尝试的另一种方法(由于jqLit​​e没有.replaceAll(),因此使用.after().remove()

if(slides) {
    console.log(element);
    template = angular.element($compile(tElement.html())(scope));

    var oldElement = element;
    element = element.after(template);
    oldElement.remove();

    console.log(element);

    new Swipe(element[0], { /* ... */ });
}