javascript - 通过 ng-include 重用之前实例化的模板

标签 javascript angularjs angularjs-ng-include

我需要 <select>在表单上控制剩余的可用输入。通过绑定(bind)<select>,可以使用 Angular 轻松实现这一点。到 ng-include 的 src .

问题是每次用户更改所选值(以及 src 模板)时,Angular 都会从头开始编译模板并附加新的范围。这具有每次删除所有输入数据的效果。用户希望如果他们改回之前选择的选项,他们之前输入的所有字段数据仍然会在那里。

是否有任何内置方法可以实现所需的行为?理想的选择是 ng-include会重用以前编译的模板和关联的范围吗?

一种解决方法是 ng-include所有模板,并使用 ng-show只显示当前的一个。虽然这看起来很重,但页面上有很多不必要的 DOM 元素。 (特别是对于我的用例,大约有 20 个不同的模板,并且整个 <select> 元素和动态模板控件可能会在单个页面上重复最多 40 次。)

这是一个jsFiddle 。期望的结果是,当将下拉列表更改为模板 2 并返回到 1 时,模板 1 上的计数器会保留下来。

最佳答案

我发现这个问题很有趣。如果没有将模型放入服务中(这可能是正确的方法),我认为没有一种内置方法可以使用 ng-include 缓存模板而不使用 ng-repeat,如 in this fiddle 所示。 .

<div ng-controller="Ctrl">
    <select ng-model="template" ng-options="t.name for t in templates">
     <option value="">(blank)</option>
    </select>
    url of the template: <tt>{{template.url}}</tt>
    <hr/>
    <div ng-repeat="t in templates" ng-include="t.url" ng-show="template.name == t.name">
     </div>
  </div>

正如您所指出的,该解决方案的缺点是最终会在 DOM 中产生大量元素。

为了好玩,我编写了一个 ng-include 版本,它可以缓存模板元素并重用它。在最坏的情况下,您最终仍然可能创建同样多的 DOM 节点,但由于它们仅按需创建,并且在任何给定时间 DOM 中只有一个节点,因此从 Angular Angular 来看,它应该保持相当高效。

Here is the fiddle for this directive

.directive('cacheInclude', function ($compile, $http, $templateCache) {
    return {
        link: function (scope, element, attrs, ctrl) {
            var cache = {};
            var currentElement = element;
            var replaceCurrent = function(cacheEntry) {

                currentElement.replaceWith(cacheEntry);
                currentElement = cacheEntry;
            };
            scope.$watch(function(){
                return scope.$eval(attrs.src);
            }, function () {
                var src = scope.$eval(attrs.src);

                if (!cache[src]) {
                    $http.get(src, {cache: $templateCache}).then(function (result) {


                        cache[src] = $compile(result.data.trim())(scope.$new());
                        replaceCurrent(cache[src]);
                    });
                } else {

                    replaceCurrent(cache[src]);
                }
            });
        }
    }
})

它不是“内置的”,但我认为这是一个很好的中间解决方案。请注意,该指令“仅用于示例”,并且仍然需要错误处理等。

关于javascript - 通过 ng-include 重用之前实例化的模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28654061/

相关文章:

javascript - 尝试调试相邻 JSX 元素错误

javascript - AngularJS onload - 未捕获的 ReferenceError : $scope is not defined

angularjs - AngularJS 中的条件 ng-include

javascript - ExpressJS 为什么在 DELETE 方法之后调用我的 GET 方法?

javascript - ng-include 中使用的指令不起作用

javascript - ng-包括 : How can I maintain data in $scope after changing views?

dom 节点太多的 Javascript 性能问题?

Javascript 对象枚举语法

javascript - Stripe 发票项目并不总是在一张发票中一起发送

javascript - AngularJS:无法发送带有适当 CORS header 的 POST 请求