Cargando parciales ng-include desde la caché de plantilla local precargada (JST)
-
24-12-2019 - |
Pregunta
Tengo mi plantilla precargada en una matriz de cadenas de JavaScript, como var t = JST['firstTemplate']
, dónde t
seria como,
<div>This scope has a value of {{value}}</div>
¿Cómo puedo utilizar esta plantilla precargada en un ng-include
¿directiva?
Tenga en cuenta que mi plantilla en este escenario puede ser más compleja, con posibles vistas y plantillas anidadas y sus propios ámbitos y controladores anidados.Entonces, ¿no estoy seguro de si alguna de las directivas ng-bind ayudaría?
ACTUALIZAR:
Mirando la fuente de ng-include
Parece que una buena forma de hacerlo sería desacoplar la lógica de carga de la plantilla en un proveedor personalizable.
El mecanismo de carga predeterminado actual simplemente hace una $http.get
con $templateCache
como proveedor de caché.Parece que puedo inyectar el contenido de mi plantilla en JST['firstTemplate']
en el caché de la plantilla, pero tendría que hacerlo en el momento del inicio, para cada plantilla.
$templateCache.put('firstTemplate', JST['firstTemplate']);
y luego tener,
<div ng-include="firstTemplate"></div>
También podría escribir una directiva personalizada que vaya en paralelo con cada ng-include, que de alguna manera realiza este almacenamiento previo en caché de las plantillas.Eso nuevamente parece torpe.
ACTUALIZACIÓN #2
Voy a intentar anular templateCache para que utilice mi hash JST ya precargado.Publicaré los resultados si esto funciona.
Solución
Esta es la solución que encontré para trabajar, y no es un truco como si estuviera pensando anteriormente (arriba :-) Básicamente, decorar el método $ templatecache.get usando Standard $ PROPORTE.DECORATOR para que el caché se vea en mi local.caché precargado.Solo funciona
angular.module('app').config([
'$provide',
function($provide) {
$provide.decorator('$templateCache', function($delegate, $sniffer) {
var originalGet = $delegate.get;
$delegate.get = function(key) {
var value;
value = originalGet(key);
if (!value) {
// JST is where my partials and other templates are stored
// If not already found in the cache, look there...
value = JST[key]();
if (value) {
$delegate.put(key, value);
}
}
return value;
};
return $delegate;
});
return this;
}
]);
Si se pregunta por qué tengo esta cosa en JST, usamos un backend de Rails y los Rails Asset Pipeline para entregar todos los activos angulares.Las plantillas JST nos permiten agrupar todas las plantillas y cargarlas en la aplicación durante la inicialización, y evitar que normalmente se requieran rondas de servidores adicionales al obtener parciales y otro contenido de plantillas.
El parche anterior hace que todos estos funcionan con angular.
Otros consejos
En lugar de ng-include
, usar ng-bind-html
:
<div ng-bind-html="t"></div>
En su controlador, coloque la plantilla en el $scope
:
$scope.t = JST['firstTemplate'];
Necesitarás incluir ngSanitize
como un submódulo (no olvides agregar angular-sanitize.js
también):
angular.module('app', ['ngSanitize']);
Hoy me enfrento al mismo problema, aquí está mi solución:
Una directiva personalizada, que devuelve el JST "servidor/información" como plantilla:
/* jstTemplate.js */
/**
* @desc template loader for JST templates
* @example <div jst-template="server/info.html"></div>
*/
angular
.module('myApp')
.directive('jstTemplate', jstTemplate);
function jstTemplate() {
return {
restrict: 'A',
template: function(element, attrs) {
return JST[attrs.jstTemplate]();
}
}
};
Uso:
<div class="box">
<div jst-template="server/info.html"></div>
</div>
El attrs.jstTemplate
contiene el valor que proporcionamos en la directiva.
Saludos, Niklas