我正在尝试使用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}}
。但我更喜欢在我的模板中没有任何函数调用来实际获取数据。
答案 0 :(得分:1)
好的。可能有另一种方法可以实现这一点,或者可能使用包含而不是指令,但这至少是一种方式。
使用您的示例代码,您可以使用$compile
和append
跟随您的第二条路线,但您还需要为隔离范围的内容传递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>