在我的应用程序的一部分中,我有一个用户编辑单页信息(通过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)识别和执行。想法?
答案 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