如何通过绑定将模板传递给AngularJS组件

时间:2017-09-21 16:38:57

标签: javascript angularjs angularjs-components angularjs-1.5 angularjs-1.6

我想通过绑定将自定义模板传递给AngularJS组件并使用他的范围渲染它。像这样的东西(伪代码,这不起作用):

angular
  .module('myApp', [])
  .controller('mainController', ($scope) => {

    $scope.getTemplate = () => (`
      <div>
        <span>{{$ctrl.name}}</span>
      </div>
    `)
  })
  .component('myComponent', {
    controller: ($scope, $compile) => {
      const $ctrl = $scope.$ctrl;

      $ctrl.$onInit = () => {
        $ctrl.name = 'Hello World!';
      };

      $ctrl.compileTemplate = () => $compile($ctrl.template())($scope);
    },
    bindings: {
      template: '&'
    },
    template: `
      <div>
        My dynamic content: {{$ctrl.compileTemplate()}}
      </div>
  `
  });

用法:

<div ng-controller="mainController as $ctrl">
  <my-component template="$ctrl.getTemplate()"></my-component>
</div>

预期结果:

<div>
  My custom content:
  <div>
    <span>Hello World!</span>
  </div>
</div>

有什么办法吗?

2 个答案:

答案 0 :(得分:0)

您可以使用$compile服务创建指令来处理所涉及的DOM操作。

以下工作代码段实现了一个属性指令compile,它编译控制器作用域中属性的输入值。它基本上将您的模板添加到指令附加到的元素的内部内容中,最后编译它。

&#13;
&#13;
angular.module('app', [])
  .run(($rootScope) => {  
    $rootScope.name = 'world';    
    $rootScope.template = `
      <label>Name</label>
      <input type="text" ng-model="name">
      <h2>Hello {{ name }}!</h2>
    `;
  })
  .directive('compile', ($compile) => {
    return (scope, element, attrs) => {
      scope.$watch(
        scope => scope.$eval(attrs.compile),
        value => {
          element.html(value);
          $compile(element.contents())(scope);
        }
      );
    };
  })
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.js"></script>
<div ng-app="app">
  <div compile="template"></div>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

如果你想要动态模板,你可以利用你可以将一个函数传递给组件template的事实,在函数是可注入的组件中,我引用你的this问题了解更多信息,但这是主要的想法:

angular
  .module('myApp', [])
  .factory('tempalteFactory', {
      return getTemplate() {
          retrun '<b> yep </b>';
      }
  })
  .component('myComponent', {
    controller: ($scope, $compile) => {
      const $ctrl = $scope.$ctrl;

      $ctrl.$onInit = () => {
        $ctrl.name = 'Hello World!';
      };   

    },
    template: function($element, $attrs, templateFactory) {
          'ngInject';

          return templateFactory();
    }    
  });