2017-09-30 7 views
3

リソースを表示する前に、そのリソースが利用可能かどうかを確認したいと思います。私はここAngularJSであることを行うには良い方法を見つけた:Angular js - isImage() - check if it's image by urlAngulerJSのシンプルな工場は無限のサイクルループを引き起こします - なぜですか?

しかし、私はそれを実装しようとするたびに、無限ループがトリガされ、私はcodepenで最も単純な形式に機能を削減しても: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> 

誰でもこの動作を私に説明し、解決する手助けはできますか?

答えて

3

Angularはダイジェストループを実行し、テンプレートを解釈します。それは{{testImage('anylink')}}を見て、それを呼び出します。これにより、Utils.isImageが呼び出され、約束が得られます。約束はtestImageに返されますが、testImage自体は何も返さないので、テンプレートには何も表示されません。

少し後で、約束が解決します。 Angularはこれを見るので、ダイジェストループを実行し、テンプレートを解釈します。それは{{testImage('anylink')}}を見て、それを呼び出します。これでUtils.isImagesが呼び出され、プロムが作成されます...ああ、私たちはループしています。それは約束を作成するisImageを呼び出し、その約束が解決すると、テンプレートをもう一度解釈し、すべてを開始して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

+0

これは動的に機能しますか?データベースから読み取るために何百もの画像が存在する可能性があります – Leon

+0

ありがとうございました – Leon

+1

データベース要求を作成し、結果をループして結果をいくつかの配列に保存する必要があります。テンプレートが補間されるたびにではなく、コントローラーが作成されたときにこれを1回だけ確実に実行する必要があります。 –

0

$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"; 
     }); 
    }; 

あなたのコードペンでテストしました。

+0

ハードコーディングされた文字列を返すとどのように役立ちますか? – charlietfl

+0

この特定のコードビットは構文エラーがあるようです... $ scope.cacheが "result"に設定されていないため、関数は決して実行されず、決して設定されません。 – Leon

関連する問題