2016-11-01 8 views
1

私は、ユーザーの嗜好に応じてSVGイメージのいくつかのパスに色を適用するユーザーアバター指令を持っています。非常に長いスレッドの各コメントに適用され、複数のコメントを持つユーザーごとに繰り返しコンパイルされます。同じユーザーに対して繰り返し呼び出されるAngularJSディレクティブをキャッシュするにはどうすればよいですか?

angular.module('someModule') 

.directive('userAvatar', ['$timeout', '$http', function ($timeout, $http) { 

    return { 
     restrict: 'E', 
     replace: true, 
     template: '<object type="image/svg+xml" data="/path/user-avatar.svg"></object>', 

     link: function (scope, element, attrs) { 
      scope.image = attrs.image; 

      var init = function() { 
       $timeout(function() { 

        var img = scope.image; 
        var path1, path2, path3; 

        // here we apply fill color to the paths by path ID 
       }, 0); 
      }; 

      var waitForRender = function() { 
       if ($http.pendingRequests.length > 0) { 
        // wait for all templates to be loaded 
        $timeout(waitForRender); 
       } else { 
        init(); 
       } 
      }; 

      $timeout(waitForRender); 
     } 
    }; 
}]); 

たちは、私はそれぞれの固有のIDのために、スタイルを作らSVGグラフィックになるディレクティブの出力をキャッシュする方法を、各コメント用のユーザーIDを渡すことができますと仮定すると:

ここでは省略したバージョンですか?

答えて

0

これは、JavaScriptライブラリと同じ方法で行うことができます。オブジェクトを作成し、そのパラメータをキーとして値として隠します。それから、あなたがそれを必要とするとき、それがそこにあるかどうかを見て、再生の代わりにそれを使用します。

var cache = {}; 

link: function (scope, element, attrs) { 
    // ... 
    var id = getUserIdSomehow(); 

    if (!cache[id]) { 
     cache[id] = createNewImage(id); 
    } 

    return cache[id]; 
    // ... 
} 

明らかに擬似コードではありません。基本的には、スコープ内またはグローバルレベル(正確なユースケースに応じて)の変数を用意し、作成したイメージを保存して、作成していない場合にのみ作成します。

+0

ありがとうございました。これは私が気にしていたことですが、ディレクティブテンプレートをコンパイルして格納する方法は不明です。そのステップに対処するためにあなたの答えを強化してもよろしいですか? – isherwood

+0

また、 'cache'はどこにありますか? '$ rootScope'を使って同様のことを試しました。明らかに、ディレクティブの子スコープの外に存在する必要があります。 – isherwood

+0

ああ、私はあなたのサンプルコードで十分に近く見ていませんでした。私はあなたの指示にも直接SVGのテンプレートがあったことに気付かなかった。おそらく、それを別のディレクティブの一部としてキャッシュし、それを使ってSVGを表示することになります(基本的に '

{vm.userAvatar}
'のテンプレートを持ち、コンポーネントではなくSVG自体を変数として扱います)。 – samanime

1

$cacheFactoryは、ジョブ$cacheFactoryを実行する可能性があります。

serviceと異なり、シングルトンオブジェクトとしてのserviceもキャッシュに使用できます。ビューがなくなっても破棄されません。あなたのコメントに基づいて

、次の行う可能性があります:

は、カスタムキャッシュファクトリを作成します。 (あなたは、ウィンドウ/タブを閉じるまで)

angular.module('someModule').factory('superCache', ['$cacheFactory', function($cacheFactory) { 
    return $cacheFactory('super-cache'); 
}] 

次に、あなたの指示にsuperCacheを注入し、この工場では、種の永続的なストレージになることに注意してください。ディレクティブリンク関数では、次のようなことができます。

var dataUsedInTemplate; 
if(superCache.get(uniqueID)){ 
    // getting cached data if we already have it 
    dataUsedInTemplate = superCache.get(uniqueID); 
}else{ 
    // oops, we don't have data for this user yet, let's put it together 
    dataUsedInTemplate = createUserSpecificTemplateData(uniqueID); 

    // cache data for later use 
    superCache.put(uniqueID, dataUsedInTemplate); 
} 
+0

'scope.image'?コンパイルされたテンプレートを保存することはできません。ダイジェストサイクルごとに再コンパイルされます。 – oKonyk

+0

スタイリングがその子パスに適用された後は、テンプレートのオブジェクト要素になります要素。 – isherwood

+0

私は参照してください更新された答えを参照してください。あなたのサンプルコードをPlunkerに入れてリンクを共有するための助けが必要な場合 – oKonyk

0

私は、ユーザーの設定を管理するサービスを作成します。そうすれば、必要に応じてディレクティブに触れることなく将来の実装を変更できます。この設定を無期限に保存する必要がない場合は、データベースまたは$cookiesに保存することをお勧めします。

+0

答えをありがとう。この場合、現在認証されているユーザに関連付けられていないコメントがロードされています – isherwood

0

あなたはCSSとng-includeであなたが望むことができるかもしれません。他の人が示唆しているように、どのアバターカラーが非常に複雑であるか、AJAXコールを伴うかを計算すると、後ですばやく検索できるように値を保存できます。

以下のコードでは、ユーザー "タイプ"が既に計算されているかどうかを確認し、見つからない場合は計算します。

SVGのクラスによっては、CSSで設定した色が異なります。 Ng-includeは、SVGマークアップを直接DOMに挿入するので、CSSでそれを操作できます。

など。

マークアップ:

<ng-include class="avatar" 
    src="/path/user-avatar.svg" 
    ng-class="getUserType(user)"></ng-include> 

CSS:

.avatar.type-a path1{ 
    fill: red; 
} 
.avatar.type-a path2{ 
    fill: white; 
} 
.avatar.type-a path3{ 
    fill: blue; 
} 

.avatar.type-b path1{ 
    fill: red; 
} 
.avatar.type-b path2{ 
    fill: green; 
} 
.avatar.type-b path3{ 
    fill: yellow; 
} 

JS:

app.controller('MyController', ['$scope', function($scope){ 

    $scope.getUserType = function(user){ 
     // Don't recalculate the class for this user if you've already done it 
     if(typeof user.type !== 'undefined'){ 
      return user.type; 
     } 
     // This is where your logic goes if you need to calculate the user type 
     else if(user.ID == 1){ 
      user.type = 'type-a'; 
     } 
     else{ 
      user.type = 'type-b'; 
     } 
     return user.type; 
    } 

}]); 
+0

'currentColor'疑似コードか、それはどこから来たのですか? – isherwood

+0

'currentColor'は擬似コードではありません。現在の' color'スタイルが問題のルールに適用されます。この場合、 'fill'は' color'と同じ値を継承します。より詳しい説明はこちらをご覧ください:https://developer.mozilla.org/en/docs/Web/CSS/color_value#currentColor_keyword – Stafree

+0

私は参照してください。このアプローチでは、ユーザーのアバターで3つの異なる色を3つの異なるパスに適用するにはどうすればよいですか? – isherwood

関連する問題