Angularjs:使用数据动态加载指令

时间:2017-03-30 01:51:38

标签: javascript angularjs typescript

我正在尝试使用angularjs创建一个动态框架。我使用webapi加载部分,其中包含有关其使用的指令的数据以及应该在该指令中使用的数据。我发送的数据可能如下所示:

[
    {
        id: "section1",
        directive: "<my-directive></my-directive>",
        content: {
            title: "This is a title",
            text: "This is a text"
        }
    },
    {
        id: "section2",
        directive: "<my-other></my-other>",
        content: {
            title: "This is another title",
            list: ["This is a text", "This is another text"]
        }
    }
]

当我加载这些数据时,我将指令转换为带有$ compile的元素。

angular.forEach($sections, (value, key):void => {
    value.directive = $compile(value.directive)($scope);
}

所以我实际上可以在视图中加载这些数据,如下所示:

<div ng-repeat="section in sections">
    {{section.directive}}
</div>

首先,我的视图中没有显示,所以如何解决这个问题? 然后我有第二个问题。当我实际上将此指令加载到视图中时,我将如何访问应该在此指令中使用的数据?我确实在这些部分添加了一个ID。这就是我尝试过的:

angular.forEach($sections, (value, key):void => {
    value.directive = $compile(value.directive)($scope);
    var parent = angular.element('#sectionsparent'); //The parent element has this id
    parent.append(value.directive);
}

这样就显示了section元素,但是我无法访问应该在指令中加载的数据。

提前感谢您的帮助,如果您需要更多信息,请与我们联系。

编辑:

最终加载指令时,我希望能够访问属于该部分的数据。因此,如果我们在示例数据中采用第一部分,我希望能够在指令的模板中执行以下操作:

<!-- This file is myDirectiveTemplate.hmtl -->
<div id="{{id}}>
    <h1>{{title}}</h1>
    <p>{{text}}</p>
</div>

我不在乎是否必须通过viewmodel对象访问这些属性,因此它将是{{vm.id}}而不是{{id}}。但我更喜欢在我的模板中没有任何函数调用来实际获取数据。

1 个答案:

答案 0 :(得分:1)

好的。可能有另一种方法可以实现这一点,或者可能使用包含而不是指令,但这至少是一种方式。

使用您的示例代码,您可以使用$compileappend跟随您的第二条路线,但您还需要为隔离范围的内容传递html属性并将其与新的$ scope绑定该部分补充说。 (你还需要包装$ timeout,以便在最初渲染之后查询DOM。)

var app = angular.module('app', []);
app.controller('AppCtrl', function($scope, $compile, $timeout) {  
  $scope.sections = [
      {
          id: "section1",
          directive: "my-directive",
          content: {
              title: "This is a title",
              text: "This is a text"
          }
      },
      {
          id: "section2",
          directive: "my-other",
          content: {
              title: "This is another title",
              list: ["This is a text", "This is another text"]
          }
      }
  ];
  
  // Need to timeout so rendering occurs and we can query the DOM.  
  $timeout(() => {
    angular.forEach($scope.sections, (section) => {
      let newScope = $scope.$new();
      newScope.content = section.content;
      let dir = section.directive;
      let compiled = $compile(`<${dir} content="content"></${dir}>`)(newScope);
      let parent = angular.element(document.querySelector('#' + section.id));
      parent.append(compiled);
    });
  });
});

app.directive('myDirective', function() {
  return {
    restrict: 'E',
    scope: {content: '='},
    template: `<div>
        <h1>{{content.title}}</h1>
        <p>{{content.text}}</p>
      </div>`,
  };
});

app.directive('myOther', function() {
  return {
    restrict: 'E',
    scope: {content: '='},
    template: `<div>
        <h1>{{content.title}}</h1>
        <ul>
          <li ng-repeat="item in content.list">{{item}}</li>
        </ul>
      </div>`,
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app" ng-controller="AppCtrl">
  <div ng-repeat="section in sections" id="{{section.id}}"></div>
</div>