【问题标题】:Using $http and $templateCache from within a directive doesn't return results在指令中使用 $http 和 $templateCache 不会返回结果
【发布时间】:2012-11-01 05:36:22
【问题描述】:

我正在尝试创建一个可以加载模板的指令。然后模板将被缓存,因此当您第二次单击该元素时,它不会尝试加载它,而是从 $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/

请注意,您可以根据需要多次单击 Click Event 链接,但是“Click Directive”链接仅在您先单击时才有效,如果您先单击“Click Event”链接,则根本无效。

非常感谢任何想法。

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    我玩过一些,并使用了 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");
            });
        }
    }​
    

    【讨论】:

    • 感谢您的回复。你是对的,问题在于绑定。我将代码更改为 $scope.$apply 就像 ng-click 一样,它起作用了。见这里:jsfiddle.net/3ea64/1
    • 哇,感谢 user43685。那个应用范围正是我需要让 http 在我的指令中正常工作的东西
    【解决方案2】:

    我建议创建一个单独的服务来完成这项工作:

    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();
    }]);
    

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

    【讨论】:

    • 您不需要在$http.get() 中使用$q,因为$http 已经返回了promisereturn $http.get(keyOrUrl, { cache: true }).success(function (html) { $templateCache.put(keyOrUrl, html); return html; });
    猜你喜欢
    • 2015-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-10
    • 1970-01-01
    • 2013-11-15
    相关资源
    最近更新 更多