Angular Directive不使用interval更新元素

时间:2016-08-08 12:44:24

标签: angularjs angularjs-directive

我有这个指令

angular.module('mydirectives').directive('slideShow', function ($interval) {
return{
    scope:{slideShow:'=slideShow'},
    link:function(scope, element, attrs){         

        element.css("background-size","cover");
        element.css("background-repeat","none");
        element.css("background-position","center center");
        element.css("background-blend-mode","color");
        element.css("background-color","rgba(0, 0, 0, 0.5)");

        scope.index=0;

        function nextSlide()
        {
            if(!scope.slideShow) return;
            if(scope.slideShow.sources.length===0) return;

            var url=scope.slideShow.sources[scope.index++];
            if(scope.index>=scope.slideShow.sources.length) scope.index=0;

            element.css({'background-image': 'url(' + url +')'});
        }

        nextSlide();
        var interval= $interval(nextSlide,3000)
        scope.$on("$destroy",function(){
            $interval.cancel(interval);
        })
    }
}
});

这就是我应用它的方式

<section class="primary" slide-show="slideShow">

现在提供属性的控制器&#34; slideShow&#34;通过http请求获取值。当它返回响应时,它会像这样设置slideShow的值

$scope.slideShow={sources:["http:\\sources\someimage.jgp"]}  
webApi.getHomePageModel().then(function(model){
   $scope.model=model;
   $scope.slideShow=model.slideShow;        
},function(error){
   console.dir(error);
});

问题:当这只运行幻灯片的默认值时,设置了元素的背景图像但是在对http的响应之后,新值设置为slideShow但是当区间函数&#34; nextSlide&#34;执行后,后台图像不会更新。在调试器中,我可以看到正确地拾取了url值,但是元素没有更新。

编辑:我犯了一个愚蠢的错误,更新的模型并不像预期的那样源中的元素不是预期的字符串(它们是作为复杂对象而不是字符串值生成的。)所有现在工作。也不需要范围。$ applyAsync因为$ interval服务为你处理

2 个答案:

答案 0 :(得分:0)

如果您使用的是setInterval,那么您需要手动重新运行angular的digetst周期:

function nextSlide()
    {
        if(!scope.slideShow) return;
        if(scope.slideShow.sources.length===0) return;

        var url=scope.slideShow.sources[scope.index++];
        if(scope.index>=scope.slideShow.sources.length) scope.index=0;

        element.css({'background-image': 'url(' + url +')'});

        scope.applyAsync();  //this line!
        //May not work in older angular versions, if such you should use scope.apply()

    }

答案 1 :(得分:0)

我使用了这个实现

angular.module('app').directive('slideShow', function ($interval) {
return{
    scope:{slideShow:'=slideShow'},
    link:function(scope, element, attrs){         
        var index=0;


        function nextSlide()
        {
            if(!scope.slideShow) return;
            if(scope.slideShow.images.length===0) return;

            var url=scope.slideShow.images[index++];
            if(index>=scope.slideShow.images.length) index=0;               
            element.css({'background-image': 'url(' + url +')'});
        }

        var interval=false;
        var watchSlideShow=scope.$watch("slideShow",function(){
            if(!scope.slideShow) return;
            if(scope.slideShow.images.length===0) return;
            if(interval) return;

            nextSlide();
            var interval= $interval(nextSlide,5000);
        });

        scope.$on("$destroy",function(){
            $interval.cancel(interval);
            watchSlideShow();
        });
    }
}
});