在数据加载角指令模板更新 [英] Angular Directive Template Update on Data Load

查看:141
本文介绍了在数据加载角指令模板更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个指令正在通过API调用接收其数据。该指令本身工作正常,问题出现的(我相信)的,因为指令API调用完成之前加载。这导致整个事情只是不工作。不是我期望的输出,我只是得到 {{}用户}

I have a directive whose data is being received via an api call. The directive itself works fine, the problem arises (I believe) because the directive is loaded before the api call finishes. This results in the whole shebang just not working. Instead of my expected output, I just get {{user}}.

我的指令是这样的:

app.directive('myDirective', function() {
  return {
    restrict: 'A',
    require: '^ngModel',
    scope: {
      ngModel: '=',
    },
    template: '<tbody style="background-color: red;" ng-bind-html="renderHtml(listing_html)"></tbody>',
    controller: ['$scope', '$http', '$sce',
      function($scope, $http, $sce) {
        $scope.listing_html += "<td>{{user.name}}</td>"
        $scope.renderHtml = function(html_code) {
          return $sce.trustAsHtml(html_code);
        };
      }
    ],
    link: function(scope, iElement, iAttrs, ctrl) {
      scope.$watch('ngModel', function(newVal) {
        // This *is* firing after the data arrives, but even then the
        // {{user}} object is populated. And the `user in ngModel` doesn't
        // run correctly either.
        console.log(scope.ngModel);
        scope.listing_html = "<tr ng-repeat='user in ngModel'><td>{{user}}</td></tr>"
      })
    }

  };
});

和我的HTML简直就是

And my html is simply

<table my-directive my-options='{"Name": "name", "Email": "email"}' ng-model='userData'></table>

我创建了一个 plunker 一吨的意见,希望有助于解释这个问题。

I've created a plunker with a ton of comments to hopefully help explain the issue.

此问题的非常的类似<一个href=\"http://stackoverflow.com/questions/13141816/angular-js-update-scope-and-template-after-jsonp-request\">this 之一,与解决方案的主要区别不工作。添加 NG-斗篷雷只是使它不会显示。
这也可能是值得注意的是,我一直在使用作为参考方式来构造一个指令。

This question is very similar to this one, with the key distinction of that solution not working. Adding ng-cloak to mine just makes it not display. It may also be worth noting that I've been using this as reference on the way to construct a directive.

推荐答案

我不是100%肯定,但我相信, ngBindHtml 不会帮助你在这种情况下。结果
ngBindHtml 是用于显示一些正常的HTML,但你要显示一些角,魔术HTML。结果
对于您需要 $编译的HTML的东西,是角感知和链接编译后的HTML到一个范围

I am not 100% sure, but I believe that ngBindHtml will not help you in this case.
ngBindHtml is for displaying some "normal" HTML, but you want to display some Angular, magic HTML.
For that you need to $compile the HTML to something that is Angular-aware and link the compiled HTML to a scope.

我用下面的方法(有明显效果好):

I used the following approach (with apparently good results):

controller: function ($scope, $element, $compile) {
  var html = createTmpl(angular.fromJson($scope.myOptions));
  $scope.$watch('ngModel', function (newVal) {
      var elem      = angular.element(html);   // Creating element
      var linkingFn = $compile(elem);          // Compiling element
      linkingFn($scope);                       // Linking element
      $element.html('');                       // Removing previous content
      $element.append(elem);                   // Inserting new content

      // The above is purposedly explicit to highlight what is 
      // going on. It's moe concise equivalent would be:
      //$element.html('').append($compile(html)($scope));
  });

其中, createTmpl()被定义为顾及 myOptions ,并返回相应的模板与创建表一个标题行(根据 myOptions 键)和数据行被定义为 myOptions 属性的值:

where createTmpl() is defined to take into account myOptions and return the appropriate template for creating a table with a header-row (based on the keys of myOptions) and data-rows with the properties defined as myOptions's values:

function createTmpl(options) {
    // Construct the header-row
    var html = '<tr>';
    angular.forEach(options, function (value, key) {
        html += '<th>' + key + '</th>';
    });
    html += '</tr>\n';

    // Construct the data-rows
    html += '<tr ng-repeat="user in ngModel">';
    angular.forEach(options, function (value, key) {
        html += '<td>{{user' + value + '}}</td>';
    });
    html += '</tr>\n';

    // Return the template
    return html;
}


又见这个 短演示 结果
<子>
当然,这仅用于演示之用,并不处理一切生产就绪的应用程序应该(例如占错误,缺少的属性,在 myOptions 的变化和诸如此类的东西)。


See, also, this short demo.
Of course, this is for demonstration purposes only and does not handle everything a production-ready app should (e.g. accounting for errors, missing properties, changes in myOptions and whatnot).

更新

我有非常强的赛区,所以我做了上面,以支持嵌套属性code略有修改。例如。给定的对象具有以下结构:

I had very strong competion, so I did a slight modification of the code above in order to support nested properties. E.g. given an object with the following structure:

user = {
    name: 'ExpertSystem',
    company: {
        name: 'ExpertSystem S.A.',
        ranking: 100
    }
};

我们可以,只要定义在我们表的列中显示的公司名称 myOptions 是这样的:

we can have the company name displayed in a column of our table, just by defining myOptions like this:

myOptions='{"Company name": "company.name"}

这篇关于在数据加载角指令模板更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆