使用数据库中的内联代码

时间:2017-11-22 23:06:01

标签: angularjs templates browser-cache

在我的应用程序的一部分中,我有一个用户编辑单页信息(通过HTML编辑器:内容工具)。我已经开始修改这个功能代码,以便他们编辑的页面是用动态模板构建的,而不是硬编码的。

目前,我将编辑/可编辑的数据存储在数据库表中。我还将模板定义存储在数据库表中。我使用的模板只是以前硬编码的HTML代码,所以我知道模板是有效的。

此时我正确地从服务器接收JSON包装器中的所有数据就好了。什么是无效的是呈现内容 - 页面保持空白。我确定问题是我对AngularJS缺乏了解以及它是如何执行的。

[更新:代码和以下执行说明在使用@Wes H和@ 31PIY的输入重新处理后已更新。显然,不再是$ templateCache问题。] 具体来说,我的HTML是:

<body ng-app>
    <div ng-controller="PageEditController">
        <div ng-bind-html="renderHtml(htmlTemplate)"></div>
    </div>
</body>

[注意:renderHtml是$ sce.TrustAsHtml()的包装器,以确保Angular不剥离HTML]

我的javascript的相关部分是:

        $http({
            method: 'POST',
            url: 'https://my-api-access-point',
            data: parms
        }).then(function successCallback(response) {
                var resp = response.data['Items'];
                var data = {};
                if (resp)
                    data = resp[0];
                console.log("jsLoadScreen Data: ", data);
                $scope.models.fields = data;
                console.log('replacing template: ', $scope.models.fields['template']);
                $scope.htmlTemplate = $scope.models.fields['template'];

控制台输出是:

jsLoadScreen Data: {UID:"1"
 left:"<h1>↵    One↵</h1>"
 right:"<h2>↵    Two↵</h2>"
 screenId:"1"
 template:"        <div class="row">↵            <div class="column">↵                <div data-editable data-name="left" ng-bind-html="renderHtml(models.fields.left)">↵                </div>↵            </div>↵            <div class="vl"></div>↵            <div class="column">↵                <div data-editable data-name="right" ng-bind-html="renderHtml(models.fields.right)">↵                </div>↵            </div>↵        </div>"

replacing template:         <div class="row">
            <div class="column">
                <div data-editable data-name="left" ng-bind-html="renderHtml(models.fields.left)">
                </div>
            </div>
            <div class="vl"></div>
            <div class="column">
                <div data-editable data-name="right" ng-bind-html="renderHtml(models.fields.right)">
                </div>
            </div>
        </div>

我已经确认模板代码是在页面上加载的(通过&#34;查看源代码&#34;)。但是,加载后,该模板代码中不会执行任何javascript或AngularJS标记。

我已经尝试了几个步骤来执行此代码,包括在我的承诺中添加另一个.then()来触摸模板中的一些变量以强制刷新,以及各种不幸的尝试导致延迟在有竞争条件的情况下的过程。没有运气。

我是否在AngularJS这样奇怪的水域中,我应该放弃并在服务器端组合模板和数据并使其成为单个AJAX操作而不是尝试执行这两步:(1)AJAX插入新的HTML模板,一旦插入然后(2)AJAX将新数据插入新的HTML模板?或者我应该对新插入的模板(或插入模板时)将其注册为javascript执行的东西?

我在SO上看到的最接近的描述是:How $templateCache works?Load HTML template from file into a variable in AngularJs,但我无法完全理解他们所说的内容以及我尝试做的事情。

更新: 在完成下面的回复之后,我很接近。有了@Wes H和@ 31piy的信息,我现在已经验证HTML正确加载到页面上(如#34;查看源代码&#34;在Chrome上的开发人员工具中)。但是,各种Angular命令(ng-bind-html(renderHtml ...))和第三方工具触发器(数据可编辑)似乎不会被Angular解释,所以我有HTML但没有javascript活动与之相关。我的猜测是插入的HTML模板以某种方式放在DOM中,但实际上并没有被Angular(或javascript)识别和执行。想法?

4 个答案:

答案 0 :(得分:1)

假设所有相关配置都在AngularJS应用中完成,我认为您根本不需要使用$templateCache。为什么?您希望在HTML中设置数据库中的HTML模板(如果我理解正确的话)。

为此,您只需使用ng-bind-html将HTML内容绑定到模板中的HTML元素即可。这是一个例子:

$http.post('https://my-api-access-point', parms)
  .then(function successCallback(response) {
    // ... Your code
    // Assign the template to a scope variable here
    $scope.htmlTemplate = $scope.models.fields['template'];
    // ... Your code
  });

现在,范围中有一个变量htmlTemplate,它可以直接绑定到HTML模板,如下所示:

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

这样,htmlTemplate的内容将显示在div元素下。您需要确保在应用中正确配置了ngSanitize模块。

答案 1 :(得分:1)

$ templateCache - 正如您列出的第一个link所述,它可用作任何模板URL请求的缓存实用程序,如templateUrl,ng-include等。

除此之外,您还可以使用$ templateCache作为键值缓存存储。当您使用$ templateCache.put(&#39; KEY&#39;,&#39; HTML字符串&#39;)时,任何模板URL请求都会在发出网络请求之前检查存储的密钥。在您的情况下,您是手动将商店添加到密钥&#39; edit.html&#39;,因此它将始终检索您的值。密钥可以是任何唯一的字符串,但不一定是文件名。

根据文档,你正在尝试做的事情应该有效。但是,在AngularJs中包含模板(缓存与否)的典型方法是使用ngInclude。

如果将<script></script>块替换为:

<div ng-include="'edit.html'"></div>

将呈现HTML和来自$scope.models.fields['template']的任何绑定。注意密钥周围的额外引号。

另一个可能棘手的部分是确保在您尝试访问$http中的缓存模板之前解决ng-include返回的承诺。那个31piy的建议使用ng-bind-html来监视$ scope并在promise结算时更新,这可能更简单。

答案 2 :(得分:0)

首先,免责声明......我根本不认识AngularJS,所以请带上一粒盐!

话虽如此,在阅读本文后,我看了一下文档:https://docs.angularjs.org/api/ng/service/$templateCache

看起来您已通过直接使用$templateCache服务以声明方式创建了缓存。现在,您需要通过以下方法之一进行渲染:

myApp.component('myComponent', {
   templateUrl: 'edit.html'
});

$templateCache.get('edit.html')

此外,由于您直接使用该服务,因此不需要脚本标记。根据文档,您可以采用一种方法或另一种方法。

希望有所帮助!

答案 3 :(得分:0)

除了@ 31piy&amp; amp;提到的重组外。 @Wes H,事实证明最后一步是将$compile与指令一起使用。解决方案:Compiling dynamic HTML strings from database