【问题标题】:Angular Directive not updating element using interval角度指令不使用间隔更新元素
【发布时间】:2016-09-27 20:11:40
【问题描述】:

我有这个指令

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">

现在提供属性“slideShow”的控制器通过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,但间隔函数“nextSlide " 执行然后背景图像不更新。在调试器中,我可以看到 url 值被正确提取,但元素没有更新。

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

【问题讨论】:

    标签: angularjs angularjs-directive


    【解决方案1】:

    如果您使用的是 setInterval 那么您需要手动重新运行 Angular 的摘要循环:

    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()
    
        }
    

    【讨论】:

    • 试过“scope.$applyAsync()”没有做任何事情。和 scope.$apply 抛出 inprog 错误。我尝试了另一件事。我用 url 值替换了 html,我看到的是它显示了第一个 url,即来自硬编码模型,但是在第一个间隔它清除了 html 值并且什么也不显示。是否与变量的范围有关
    【解决方案2】:

    我让它与这个实现一起工作

    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();
            });
        }
    }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 2015-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多