2012-11-01 12 views
9

Próbuję utworzyć dyrektywę, która załadowałaby szablon. Szablon zostanie zapisany w pamięci podręcznej, więc za drugim razem, gdy klikniesz element, nie będzie on próbował go wczytać, a zamiast tego otrzyma ostatnio załadowaną wartość z $ templateCache.

Zauważam, że w przypadku trafienia w pamięci podręcznej nie otrzymuję żadnej odpowiedzi z metody $ 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"); 
     }); 
    } 
} 

Utworzyłem skrzypce symulowania mój scenariusz:

http://jsfiddle.net/3ea64/

pamiętać, że można Click linku zdarzenia tyle razy, ile chcesz, ale „Kliknij dyrektywę” link działa tylko raz jeśli klikniesz pierwszy, to nie działa, jeśli najpierw klikniesz link "Kliknij wydarzenie".

Wszelkie pomysły są bardzo cenne.

Odpowiedz

9

Grałem trochę dookoła i używane buforowanie angularjs (opisano tutaj: http://docs.angularjs.org/api/ng $ http).

Oto live demo: http://jsfiddle.net/4SsgA/

Ja w zasadzie dostosowała $ http i składnia użyć dyrektywy ng kliknięcia zamiast rejestracji detektor zdarzeń wewnątrz dyrektywy (tylko dlatego, że mi się podoba bardziej :))

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

Dziękuję za odpowiedź. Masz rację, problem polega na wiązaniu. Zmieniłem kod, aby wykonać $ scope. $ Apply, podobnie jak ng-click i zadziałało. Zobacz tutaj: http://jsfiddle.net/3ea64/1/ – user43685

+0

Wow, dzięki user43685. Ten zakres zastosowania był właśnie tym, czego potrzebowałem, aby http działał poprawnie w mojej dyrektywie. – Erich

9

Proponuję utworzenie odrębnej usługi, która będzie wykonać zadanie:

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

Stosując to podejście doda elastyczności i izolacji do sposobu uzyskania szablony, najprawdopodobniej byś chcę, żeby to było zrobione na swój własny, niezależny sposób ...

+3

Nie musisz używać '$ q' wewnątrz' $ http.get() 'ponieważ' $ http' już zwraca 'obietnicę': 'return $ http.get (keyOrUrl, {cache: true}). success (funkcja (html) {$ templateCache.put (keyOrUrl, html); return html;});' – GFoley83

+0

Miły komentarz, dziękuję! – Lu4

Powiązane problemy