As you stated, Angular's $templateCache doesn't cache elements beyond a page reload, so you are really looking for a way to defeat the browser's cache mechanism. The simplest approach is to tell the server to send the appropriate headers to prevent caching of files served from the partials directory.
Here is an example:
I have a partial located in my web app at /partials/signin.html. With a clean browser cache, my directive will load this templateUrl and return:

Internally the following steps occur:
- My directive uses a templateUrl parameter, so the $compileProvider will attempt to fetch this.
- The $compileProvider makes an $http.get request passing in the $templateCache.
- The $http function will defer to the template cache if the url it is looking for is in the cache.
- The first time after a page refresh (and the $templateCache is new and empty) the key is not present in the $templateCache, so an XHR is made to the browser.
- The browser has no cache for the partial and makes a request to the server.
- The server responds with the content and response headers.
- The browser caches the partial based on the response header's instructions.
- In my example, the first fetch results in my typical headers for any static content from the server:
- HTTP/1.1 200 OK
- Cache-Control: public
- Expires: Wed, 26 Jun 2013 13:09:06 GMT
- Content-Type: text/html
- Last-Modified: Mon, 27 May 2013 12:53:45 GMT
- The $http service stores the contents of my response in $templateCache using the url path as a key.
- Any future requests via the $http service, until the $templateCache is cleared, will be returned from the $templateCache and no XHR request will be made.
As you can see by 7.1.3, I usually set my expires date one month in the future on all static content. If I reload the page, my directive will initiate all of the same steps as above, but step #5 is no longer the same and #6 does not occur. The browser does have a cached copy of my content and serves it up instead of hitting the server. All of the other steps remain the same.

However, in our particular case, partials are not quite static. If we want the behavior you (and I) require, we need to make sure the browser does not cache these files.
Note: some of these approaches indicate that you can defeat the server-side cache by appending a random number to the url. ie. /partials/signin.html?rand=0.233434. Fight the urge to trick the browser, as this would only result in the templateCache getting filled with your partial over and over again on each request consuming more and more memory on each partial request.
To prevent caching, I set the header Expires: -1, which results in the following.
- HTTP/1.1 200 OK
Expires: Wed, 31 Dec 1969 23:59:59 GMT
Content-Type: text/html
Last-Modified: Mon, 27 May 2013 13:34:34 GMT
Accept-Ranges: bytes
Content-Encoding: gzip
Vary: Accept-Encoding, User-Agent
Content-Length: 662
Server: Jetty(8.1.9.v20130131)
As long as my template cache is cleared, I will now see the latest version of my partial because the browser is no longer caching my content.
There are two ways to clear the template cache. One is the way we all do it; reload the page. But sometimes during development it is more helpful to just have a button on the app which can call $templateCache.removeAll(). This way, you get the newest templates but don't lose other state on the page that you need. During development, I add this button to a dev bar which I put at the top of my page.
Be careful when clearing $templateCache using removeAll(). There are many libraries (including angular-ui) that are choosing to do away with exposing template urls as actual web urls, and simply "stuff the cache" with their templates at initialization-time. This is pretty nice when distributing reusable components, since they always know what path to use to locate their templates, plus the user can still override the default templates. Because of this, there may be many more templates in your $templateCache than just your partials.
-- jim