使用数据库中的内联代码
Using inline code from database
在我的应用程序的一部分中,我有一个用户编辑单页信息(通过 HTML 编辑器:内容工具)。我已经开始修改该功能代码,以便他们正在编辑的页面是使用动态模板构建的,而不是硬编码的。
目前我正在将 edited/editable 数据存储在数据库 table 中。我还将模板定义存储在数据库 table 中。我使用的模板只是以前硬编码的 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() 的包装,以确保 HTML 不会被 Angular]
剥离
我的 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>
我已验证模板代码正在页面上加载(通过 "view source")。但是,该模板代码中的 javascript 或 AngularJS 标记在加载后不会执行。
我已经尝试了几个步骤来执行此代码,包括在我的承诺中添加另一个 .then()
以触及模板中的一些变量以强制刷新,以及各种失败的尝试导致如果存在竞争条件,则会延迟流程。运气不好。
我是否处于 AngularJS 如此奇怪的水域,我应该放弃并在服务器端组合模板和数据,并使其成为一个 AJAX 操作,而不是尝试这样做两步:(1) AJAX 插入新的 HTML 模板,插入后 (2) AJAX 将新数据插入新的 HTML 模板?或者我应该对新插入的模板(或插入模板时)做些什么来将其注册为供 javascript 执行的东西?
我在 SO 上看到的最接近的描述是: and Load HTML template from file into a variable in AngularJs 但我无法完全理解他们所说的和我尝试做的事情却没有成功。
更新:
在完成以下之前的回复后,我更接近了。借助来自@Wes H 和@31piy 的信息,我现在已经验证 HTML 已正确加载到页面上(如 Chrome 上开发人员工具中的 "view source" 所见)。然而,各种 Angular 命令(ng-bind-html(renderHtml...))和第三方工具触发器(data-editable)似乎没有被解释Angular,所以我有 HTML 但没有 javascript activity 与之相关。我的猜测是插入的 HTML 模板以某种方式放在 DOM 中,但实际上并未被 Angular(或 javascript)识别和执行。想法?
首先,免责声明...我根本不知道 AngularJS,所以请对此持保留态度!
话虽这么说,读完这篇文章后,我看了一下文档:https://docs.angularjs.org/api/ng/service/$templateCache
您似乎通过直接使用 $templateCache
服务以声明方式创建了缓存。现在,您需要通过以下方法之一渲染它:
myApp.component('myComponent', {
templateUrl: 'edit.html'
});
或
$templateCache.get('edit.html')
此外,由于您直接使用服务,因此不需要脚本标签。根据文档,您可以采取其中一种方法。
希望对您有所帮助!
假设所有相关配置都在您的 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
模块。
$templateCache - 正如您列出的第一个 所描述的,它用作任何模板 URL 请求(如 templateUrl、ng-include 等)的缓存实用程序。
除此之外,您还可以使用 $templateCache 作为键值缓存存储。当您 $templateCache.put('KEY', 'HTML string') 时,任何模板 URL 请求都会在发出网络请求之前检查存储的密钥。在您的例子中,您手动将商店添加到键 'edit.html',因此它将始终检索您的值。键可以是任何唯一的字符串,不一定是文件名。
根据文档,您尝试执行的操作应该有效。但是,在 AngularJs 中包含模板(缓存或不缓存)的典型方法是使用 ngInclude。
如果将 <script></script>
块替换为:
<div ng-include="'edit.html'"></div>
HTML 和来自 $scope.models.fields['template']
的任何绑定将被呈现。请注意键周围的额外引号。
另一个潜在的棘手部分是确保在您尝试访问 ng-include
中的缓存模板之前解决 $http
返回的承诺。这就是 31piy 关于使用 ng-bind-html
的建议,它监视 $scope 并在 promise 解决时更新,可能更简单。
除了@31piy 和@Wes H 提到的重组之外,最后一步是将 $compile
与指令一起使用。在此处找到解决方案:Compiling dynamic HTML strings from database
在我的应用程序的一部分中,我有一个用户编辑单页信息(通过 HTML 编辑器:内容工具)。我已经开始修改该功能代码,以便他们正在编辑的页面是使用动态模板构建的,而不是硬编码的。
目前我正在将 edited/editable 数据存储在数据库 table 中。我还将模板定义存储在数据库 table 中。我使用的模板只是以前硬编码的 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() 的包装,以确保 HTML 不会被 Angular]
剥离我的 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>
我已验证模板代码正在页面上加载(通过 "view source")。但是,该模板代码中的 javascript 或 AngularJS 标记在加载后不会执行。
我已经尝试了几个步骤来执行此代码,包括在我的承诺中添加另一个 .then()
以触及模板中的一些变量以强制刷新,以及各种失败的尝试导致如果存在竞争条件,则会延迟流程。运气不好。
我是否处于 AngularJS 如此奇怪的水域,我应该放弃并在服务器端组合模板和数据,并使其成为一个 AJAX 操作,而不是尝试这样做两步:(1) AJAX 插入新的 HTML 模板,插入后 (2) AJAX 将新数据插入新的 HTML 模板?或者我应该对新插入的模板(或插入模板时)做些什么来将其注册为供 javascript 执行的东西?
我在 SO 上看到的最接近的描述是:
更新: 在完成以下之前的回复后,我更接近了。借助来自@Wes H 和@31piy 的信息,我现在已经验证 HTML 已正确加载到页面上(如 Chrome 上开发人员工具中的 "view source" 所见)。然而,各种 Angular 命令(ng-bind-html(renderHtml...))和第三方工具触发器(data-editable)似乎没有被解释Angular,所以我有 HTML 但没有 javascript activity 与之相关。我的猜测是插入的 HTML 模板以某种方式放在 DOM 中,但实际上并未被 Angular(或 javascript)识别和执行。想法?
首先,免责声明...我根本不知道 AngularJS,所以请对此持保留态度!
话虽这么说,读完这篇文章后,我看了一下文档:https://docs.angularjs.org/api/ng/service/$templateCache
您似乎通过直接使用 $templateCache
服务以声明方式创建了缓存。现在,您需要通过以下方法之一渲染它:
myApp.component('myComponent', {
templateUrl: 'edit.html'
});
或
$templateCache.get('edit.html')
此外,由于您直接使用服务,因此不需要脚本标签。根据文档,您可以采取其中一种方法。
希望对您有所帮助!
假设所有相关配置都在您的 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
模块。
$templateCache - 正如您列出的第一个
除此之外,您还可以使用 $templateCache 作为键值缓存存储。当您 $templateCache.put('KEY', 'HTML string') 时,任何模板 URL 请求都会在发出网络请求之前检查存储的密钥。在您的例子中,您手动将商店添加到键 'edit.html',因此它将始终检索您的值。键可以是任何唯一的字符串,不一定是文件名。
根据文档,您尝试执行的操作应该有效。但是,在 AngularJs 中包含模板(缓存或不缓存)的典型方法是使用 ngInclude。
如果将 <script></script>
块替换为:
<div ng-include="'edit.html'"></div>
HTML 和来自 $scope.models.fields['template']
的任何绑定将被呈现。请注意键周围的额外引号。
另一个潜在的棘手部分是确保在您尝试访问 ng-include
中的缓存模板之前解决 $http
返回的承诺。这就是 31piy 关于使用 ng-bind-html
的建议,它监视 $scope 并在 promise 解决时更新,可能更简单。
除了@31piy 和@Wes H 提到的重组之外,最后一步是将 $compile
与指令一起使用。在此处找到解决方案:Compiling dynamic HTML strings from database