9

テンプレートをロードするディレクティブを作成しようとしています。テンプレートはキャッシュされるため、要素を 2 回目にクリックすると、要素は読み込まれず、代わりに $templateCache から最近読み込まれた値が取得されます。

キャッシュ ヒットの場合、 $http.get() メソッドから応答がないことに気付きました。

<html ng-app="website">
<body ng-controller="MyController">
    <a href='#' ng-click="load()">Click Event</a>
    <a href='#' click-load>Click Directive</a>

</body>
</html>​

angular.module('website', []).directive('clickLoad', function($q, $http, $templateCache) {
    return function(scope, element, attrs) {
        function loadData() {
            $http.get('http://fiddle.jshell.net', {
                cache: $templateCache
            }).then(function(result) {
                alert('loaded ' + result.data.length + " bytes");
            });

        }
        element.bind('click', loadData);
    };
});


function MyController($scope, $http, $templateCache) {
    $scope.load = function() {
        $http.get('http://fiddle.jshell.net', {
            cache: $templateCache
        }).then(function(result) {
            alert('loaded ' + result.data.length + " bytes");
        });
    }
}

シナリオをシミュレートするフィドルを作成しました:

http://jsfiddle.net/3ea64/

クリック イベント リンクは何度でもクリックできますが、「クリック ディレクティブ」リンクは、最初にクリックした場合は 1 回しか機能しません。最初に「クリック イベント」リンクをクリックすると、まったく機能しません。

どんなアイデアでも大歓迎です。

4

2 に答える 2

9

私は少し遊んで、AngularJS のキャッシュを使用しました (ここで説明します: http://docs.angularjs.org/api/ng .$http)

これがライブデモです: http://jsfiddle.net/4SsgA/

私は基本的に $http 構文を調整し、ディレクティブ内にイベントリスナーを登録する代わりに ng-click ディレクティブを使用しました (私はそれがもっと好きだから:))

HTML:

<html ng-app="website">
<body ng-controller="MyController">
    <a href='#' ng-click="load()">Click Event</a>
    <a href='#' click-load ng-click="loadData()">Click Directive</a>
</body>
</html>​

JS:

angular.module('website', []).directive('clickLoad', function($q, $http, $templateCache) {
    return function(scope, element, attrs) {
        scope.loadData = function() {
            $http({method: 'GET', url: 'http://fiddle.jshell.net', cache: true}).then(function(result) {
                alert('loaded ' + result.data.length + " bytes");
            });
        }
    };
});


function MyController($scope, $http, $templateCache) {
    $scope.load = function() {
        $http({method: 'GET', url: 'http://fiddle.jshell.net', cache: true}).then(function(result) {
            alert('loaded ' + result.data.length + " bytes");
        });
    }
}​
于 2012-11-01T07:51:01.597 に答える
9

仕事をする別のサービスを作成することをお勧めします。

YourModule.factory('Utils', ['$q', '$http', '$templateCache', function ($q, $http, $templateCache) {
    var Service = function() {

    };

    Service.prototype.TemplatePromise = function (keyOrUrl) {
        var data = $templateCache.get(keyOrUrl);

        if (data) {
            return $.when(data);
        } else {
            var deferred = $.defer();

            $http.get(keyOrUrl, { cache: true }).success(function (html) {
                $templateCache.put(keyOrUrl, html);

                deferred.resolve(html);
            });

            return deferred.promise;
        }
    };

    return new Service();
}]);

このアプローチを使用すると、テンプレートを取得する方法に柔軟性と分離が追加されます。おそらく、独自の方法でそれを実行したいと思うでしょう...

于 2013-06-20T20:57:52.247 に答える