2012-11-01 45 views
9

我正在嘗試創建一個可以加載模板的指令。然後,模板將被緩存,所以第二次點擊元素時,它不會嘗試加載它,而是最近從$ 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/

注意,您可以單擊單擊事件鏈接很多次,只要你想,但「點擊指令」鏈接只能使用一次如果您先點擊它,如果先點擊「點擊事件」鏈接,則它完全不起作用。

任何想法,不勝感激。

回答

9

我周圍玩了一下,用AngularJS的緩存(這裏說明:http://docs.angularjs.org/api/ng $ HTTP)

這裏有一個現場演示:http://jsfiddle.net/4SsgA/

我已經基本調整$ HTTP語法和使用而不是註冊內部指令的事件偵聽器的NG-點擊指令(只是因爲我喜歡它更多的:))

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"); 
     }); 
    } 
}​ 
+1

感謝您的回覆。你說得對,問題在於約束力。我改變了我的代碼來執行$ scope。$ apply就像ng-click那樣工作。看到這裏:http://jsfiddle.net/3ea64/1/ – user43685

+0

哇感謝user43685。這個適用範圍正好是我需要在我的指令中正常工作的事情 – Erich

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

使用這種方法會增加靈活性和隔離到你的模板的方式,最有可能你會想讓它成爲你自己的獨立方式...

+3

由於$ http已經返回'promise',所以你不需要在$ http.get()中使用'$ q': 'return $ http.get(keyOrUrl,{cache:true})。success(function(html){$ templateCache.put(keyOrUrl,html); return html;});' – GFoley83

+0

好評,謝謝! – Lu4