在指令中使用$ http和$ templateCache不会返回结果

use*_*685 9 angularjs

我正在尝试创建一个加载模板的指令.然后缓存该模板,以便第二次单击该元素时,它不会尝试加载它,而是从$ 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");
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

我创建了一个模拟我的场景的小提琴:

http://jsfiddle.net/3ea64/

请注意,您可以根据需要多次单击"单击事件"链接,但是"点击指令"链接仅在您首先单击它时才有效,如果您先单击"单击事件"链接,则它根本不起作用.

任何想法都非常感谢.

F L*_*has 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>?
Run Code Online (Sandbox Code Playgroud)

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");
        });
    }
}?
Run Code Online (Sandbox Code Playgroud)


Lu4*_*Lu4 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();
}]);
Run Code Online (Sandbox Code Playgroud)

使用这种方法会增加模板的灵活性和隔离性,很可能你希望它以你自己独立的方式完成......

  • 你不需要在`$ http.get()`中使用`$ q`,因为`$ http`已经返回一个`promise`:`return $ http.get(keyOrUrl,{cache:true}).success( function(html){$ templateCache.put(keyOrUrl,html); return html;});` (3认同)