【问题标题】:AngularJS simple factory causes infinite cycle loop - why? (codepen)AngularJS 简单工厂导致无限循环循环 - 为什么? (代码笔)
【发布时间】:2017-09-30 10:28:35
【问题描述】:

我想在显示之前检查图像以查看资源是否可用。我在这里在 AngularJS 中找到了一个很好的方法:Angular js - isImage( ) - check if it's image by url

但每次我尝试实现它时,都会触发一个无限循环,即使我在代码笔中将函数简化为最简单的形式:https://codepen.io/anon/pen/mBwgbE

测试图片功能(js)

$scope.testImage = function(src) {
    console.log('function triggered');
                Utils.isImage(src).then(function(result) {
             return "result";
         });
    };

用法(html)

<h3>Image link broken<h3>
<p>{{testImage('anylink')}}</p>

<h3>Image link OK<h3>
<p>{{testImage('http://lorempixel.com/400/200/sports/1/')}}</p>

谁能向我解释这种行为并帮助我解决它?

【问题讨论】:

    标签: javascript angularjs factory


    【解决方案1】:

    Angular 运行摘要循环,并解释您的模板。它看到{{testImage('anylink')}} 并调用它。这调用了 Utils.isImage,它创建了一个 Promise。 promise 返回给 testImage,但 testImage 本身不返回任何内容,因此模板什么也不显示。

    稍后,promise 解决了。 Angular 看到了这一点,因此它运行摘要循环并解释您的模板。它看到{{testImage('anylink')}} 并调用它。这调用了 Utils.isImages,它创建了一个舞会……哦,废话,我们处于一个循环中。它会调用 isImage,它会创建一个 Promise,然后当该 Promise 解析时,它会再次解释模板并调用 isImage,重新开始。

    相反,我建议当你的控制器加载时,你立即创建承诺,当它们解决时,你将你需要的任何值作为具体值粘贴到控制器上。像这样的:

    function myController($scope, Utils) {
        $scope.anyLink = null;
        $scope.sportsLink = null;
        Utils.isImage('anyLink')
            .then(function (result) { $scope.anyLink = result });
        Utils.isImage('http://lorempixel.com/400/200/sports/1/')
            .then(function (result) { $scope.sportsLink = result });
    
        $scope.heading = "My Controller";
    }
    

    然后在您的模板上,与 $scope.anyLink 或 $scope.sportsLink 交互

    【讨论】:

    • 这会动态工作吗?可能有数百张图像需要检查,从数据库中读取
    • 感谢您的解释
    • 您应该能够发出数据库请求,然后当它完成循环遍历结果时,将结果保存到某个数组中。您只需确保在创建控制器时执行一次,而不是在每次插入模板时执行此操作。
    【解决方案2】:

    $scope.testImage 会自动通过角度观察以查看 testImage 的变化。 因此,您可以使用$scope.cache 变量来停止无限循环。

      $scope.testImage = function(src) {
        console.log('function triggered');
        if($scope.cache[src] == "result")
          return "result";
        Utils.isImage(src).then(function(result) {
                 $scope.cache[src] = "result";
                 return "result";
             });
        }; 
    

    已在您的 codepen 上进行了测试。

    【讨论】:

    • 这段代码似乎有语法错误......另外,由于 $scope.cache 没有设置为“result”,函数永远不会运行,也永远不会被设置。跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    相关资源
    最近更新 更多