【问题标题】:How Do I Get HTML To Bind Properly To An Angular App如何让 HTML 正确绑定到 Angular 应用程序
【发布时间】:2016-01-03 05:04:44
【问题描述】:

我有一个 Angular 应用程序,它通过 json 向 PHP 应用程序提交数据。此应用程序向 Angular 应用程序返回一个响应对象,该对象具有一个 renderTable 属性和一个 quote 属性。

renderTable 属性是一批 HTML 文本,其中包含 angular {{expression}}。此表中还嵌入了<input> 标记,这些标记绑定到其他提到的属性引用中的 ng-models。

Quote 只不过是一个数据类,其中包含各种属性。我正在尝试使用 ng-bind-html 来显示 html 代码(确实如此),但是,我有 2 个问题需要解决。

第一个问题是我无法正确渲染 html,如果我使用 $interpolate 我从引用对象中获取值,但 <input> 标记被过滤掉(这是必要的),并且不清楚对我来说,基于 $interpolate 返回字符串这一事实,定义的绑定点仍然是动态的。

我尝试过创建自己的 unsafe 指令,但这会导致与 ng-bind-html 相同的输出。如何让我的 ajax 返回的 HTML 填充并根据还返回的对象动态更新,同时保留页面中的所有输入字段,并使用 ng-model 正确绑定?

我的代码(摘录):

 ...ajax call this is the meat of the function
 if (response.success)
 {
    $scope.crmquote = response.data.crmquote;
    $scope.quoteTable = response.data.crmtable; //this is where I initally applied $interpolate but realized it wasnt what I was looking for
    console.log($scope.quoteTable);
 }

 //this is the function I have setup to try to get angular to "trust" the html and not strip the <input> tags but it doesn tseem to work
 $scope.to_trusted = function(html_code) {
    return $sce.trustAsHtml(html_code);
 }

//this is the directive I attempted to use to achieve the desired result
 .directive('bindUnsafeHtml', ['$compile', function ($compile) {
  return function(scope, element, attrs) {
      scope.$watch(
        function(scope) {
           return scope.$eval(attrs.bindUnsafeHtml);
        },
        function(value) {
          element.html(value);
 $compile(element.contents())(scope);
        }
    );
 };
 }]);

这些是我尝试过的 HTML 代码 sn-ps:

<div ng-bind-html='to_trusted(quoteTable)' ng-show="editIF == false">

<div bind-unsafe-html='quoteTable' ng-show="editIF == false">

这是quoteTable的内容:

<table class="table table-bordered table-striped"><thead><tr><th>Description</th><th>Qty</th><th>Rate</th><th>Total</th></tr></thead><tr><td>Monthly Rent for 16'</td><td>1</td><td>$ <input type='text' ng-model='crmquote.rr16'/></td><td>$ {{crmquote.rr16 * crmquote.rr16units | number:2}}</td></tr><tr><td>Initial Delivery</td><td>1</td><td><a href='#' editable-text='crmquote.initialdelivery'>$ {{crmquote.initialdelivery}}</span></td><td>$ {{crmquote.initialdelivery * crmquote.units | number:2}}</td></tr><tr><td>Final Pickup</td><td>1</td><td><span id='editrate'>$ {{crmquote.finalunit}}</span></td><td>$ {{crmquote.finalunit * crmquote.units | number:2}}</td></tr><tr><td colspan=3 style='text-align:right'><b>Sub-Total</b></td><td id='subtotal'>$ {{crmquote.total | number:2}}</td></tr><tr><td colspan=3 style='text-align:right'><b>Taxes (8.50%)</b></td><td id='taxes'>$ {{crmquote.tax | number:2}}</td></tr><tr><td colspan=3 style='text-align:right'><b>Total Due On Delivery</b></td><td id='total'>$ {{crmquote.grandtotal | number:2}}</td></tr></table><br><table class="table table-bordered table-striped" style="margin-bottom:0;"><tr><td colspan=2><b>Estimated Future Costs</b></td></tr><tr><td>Additional Monthly Rent for 16' </td><td>$ {{crmquote.rr16 | number:2}} each</td></tr></table>

非常感谢这里的任何帮助!

【问题讨论】:

  • 我可能会误解您的示例,但我认为您的问题是 quoteTable 是一个对象,而 $sce.TrustAsHtml 需要一个字符串。如果我是对的,那么您将需要遍历对象并单独信任每个字符串。
  • @harper - quoteTable 是一个 html 字符串。请查看我的编辑。
  • editIF == false。只是出于好奇,该条件是否为真?
  • 是的。该块正在显示。
  • 嗯。我发现 angular 可以评估随机文本字符串中的 angular 很疯狂。我一直使用 $sce,但从来没有这样做过。这似乎不是一个很好的关注点分离(您可能希望在几周内以不同的方式呈现表格),所以如果您可以控制 API,我会得到一个原始 json 并从中呈现数据。

标签: html angularjs


【解决方案1】:

来自文档:

var ngBindHtmlDirective = ['$sce', function($sce) {
  return function(scope, element, attr) {
    scope.$watch($sce.parseAsHtml(attr.ngBindHtml), function(value) {
      element.html(value || '');
    });
  };
}];

-- https://docs.angularjs.org/api/ng/service/$sce#how-does-it-work-

【讨论】:

  • 是的! OP 没有正确注入 $sce!
  • 感谢您的帖子,但 SCE 被正确注入,我发现我实际上将代码绑定到了错误的模式(它是一个复杂的页面)。一旦我将它绑定到 rigth 模态,SCE 就开始完美地工作。现在的问题不是 SCE,而是为什么所有的 {{expressions}} 都没有绑定。
猜你喜欢
  • 2017-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-01
相关资源
最近更新 更多