从本地预加载(JST)模板缓存中加载ng-include部分内容

4

我有一个模板预加载在JavaScript的字符串数组中,像这样:var t = JST['firstTemplate'],其中t看起来类似于:

<div>This scope has a value of {{value}}</div>

我该如何在ng-include指令中使用预加载的模板?
请注意,在这种情况下,我的模板可能更加复杂,可能包含嵌套的视图和模板以及它们自己的嵌套作用域和控制器。因此,我不确定是否有任何ng-bind指令会有所帮助?
更新:
查看ng-include的源代码,似乎将模板加载逻辑分解为可定制化的提供程序是一个很好的方法。
当前的默认加载机制只是使用$templateCache作为缓存提供程序执行$http.get。看起来我可以将我的模板内容注入到JST['firstTemplate']中,但我必须在启动时为每个模板执行此操作。
$templateCache.put('firstTemplate', JST['firstTemplate']);

然后拥有,

<div ng-include="firstTemplate"></div>

我可以编写一个自定义指令,与每个ng-include并排出现,以某种方式进行模板预缓存。但这似乎过于笨重。
更新#2
我将尝试覆盖templateCache,以便它使用我已经预加载的JST哈希。如果成功,将发布结果。

仅供参考: <div ng-include="'firstTemplate'"></div> 如果您没有将字符串传递给ng-include,则它会尝试从具有此名称的作用域变量获取该值。 - Armin
3个回答

6

以下是我发现可行的解决方案,它不像我之前想的那样是一个黑客技巧(如上所述 :-) 基本上,使用标准的$provide.decorator修饰$templateCache.get方法,使缓存查找我的本地预加载缓存。它就这样奏效了。

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

如果你想知道为什么我在 JST 中有这些东西,那是因为我们使用 Rails 后端和 Rails 资产管道来提供所有 Angular 资产。JST 模板允许我们捆绑所有模板并在初始化期间将它们加载到应用程序中,避免了通常需要获取部分和其他模板内容时所需的额外服务器往返。上面的补丁使所有这些与 Angular 兼容。

谢谢您提供这个补丁。我之前一直在使用原始的JST源代码,现在可以开始尝试使用这个新的补丁了。 - geilt

0
今天我面临着同样的问题,这是我的解决方案:
一个自定义指令,返回JST"server/info"作为模板:
/* 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]();
        }
    }
};

使用方法:

<div class="box">
    <div jst-template="server/info.html"></div>
</div>

attrs.jstTemplate 包含了我们在指令中提供的值。

祝好, 尼克拉斯


0

使用 ng-bind-html 代替 ng-include

<div ng-bind-html="t"></div>

在您的控制器中,将模板放置在$scope上:
$scope.t = JST['firstTemplate'];

您需要将ngSanitize作为子模块包含进来(别忘了添加angular-sanitize.js):

angular.module('app', ['ngSanitize']);

从文档来看,ng-bind-html似乎不会编译模板,也不像ng-include那样为其创建一个新的作用域。我想让所有这些都发生。我是否对ng-bind-html的工作原理有误? - Shyam Habarakada
你可以使用$compile服务来实现。 - asgoth
似乎我们需要一个在 ng-include 上的选项,告诉它使用模板缓存。 - boatcoder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接