在 JavaScript 中初始化 Angular 指令
Initializing an Angular Directive in JavaScript
我的模板中有一个指令。效果很好:
<ul class="activity-stream">
<my-activity-stream-item ng-repeat="activity in vm.activities" activity="activity"></my-activity-stream-item>
</ul>
我基本上想在该模板中包含与传单地图中的弹出窗口相同的 HTML,但我不知道如何在代码中创建它。这是我尝试过的:
for (i = 0; i < activities.length; i++) {
var activity = activities[i];
var marker = L.marker([activity.location.lat, activity.location.lng]);
marker.type = activity.type;
marker.bindPopup( '<my-activity-stream-item activity="activity"></my-activity-stream-item>' );
marker.addTo( map );
}
我真的没想到它会起作用,我觉得我必须以某种方式通过范围...但我完全不知道该怎么做。
var app = angular.module('myPortal');
app.factory('TemplateService', TemplateService);
app.directive('myActivityStreamItem', myActivityStreamItem);
function myActivityStreamItem( $compile, TemplateService ) {
return {
restrict: 'E',
link: linker,
transclude: true,
scope: {
activity: '='
}
};
function linker(scope, element, attrs) {
scope.rootDirectory = 'images/';
TemplateService.getTemplate( 'activity-' + scope.activity.type ).then(function(response) {
element.html( response.data );
$compile(element.contents())(scope);
});
}
}
function TemplateService( $http ) {
return {
getTemplate: getTemplate
};
function getTemplate( templateName ) {
return $http.get('/templates/' + templateName + '.html');
}
}
(注意 - 我只使用 Angular 大约一个星期,所以如果您认为我做错了,请告诉我)
编辑: 我采纳了 Chandermani 的建议并将指令切换为 ngInclude
:
<ul class="activity-stream">
<li ng-repeat="activity in vm.activities" ng-include="'/templates/activity-' + activity.type + '.html'"></li>
</ul>
这太棒了!我还尝试使用 Josh 的建议来编译 JavaScript 中的 HTML,但是我还没有完成...
var link = $compile('<li ng-include="\'/templates/activity-' + activity.type + '.html\'"></li>');
var newScope = $rootScope.$new();
newScope.activity = activity;
var html = link( newScope );
marker.bindPopup( html[0] );
这会导致出现弹出窗口,但弹出窗口中包含的 HTML 是一条评论:<!-- ngInclude: '/templates/activity-incident.html' -->
我是否必须以某种方式将它传递给 li
中的 activity?
编辑 2: 知道了!如 Issue #4505 中所述,您需要将代码段包裹在某些东西中,所以我将 ngInclude
包裹在 div
:
中
var link = $compile( '<div><ng-include src="\'/templates/activity-incident.html\'"></ng-include></div>' );
不确定我是否理解你的问题,但你可以做的是使用 ng-include
指令,它可以使用模板表达式来动态加载模板。类似于:
<ul class="activity-stream">
<li ng-repeat="activity in vm.activities" ng-include="'/templates/activity-' + activity.type + '.html'"></li>
</ul>
您可能不需要此处的指令。
任何时候你想添加原始 HTML 到页面并让 Angular 处理它,你需要使用 $compile
服务。
在模板上调用 $compile
将 return 一个链接函数,然后可用于将范围对象绑定到。
var link = $compile('<span>{{someObj}}</span>');
将该函数链接到 scope
对象将生成一个元素,然后可以将其附加到 DOM。
//Or the scope provided by a directive, etc...
var newScope = $rootScope.$new();
var elem = link(newScope);
//Could also be the element provided by directive
$('someSelector').append(elem);
这是您需要能够告诉 Angular 处理您的 DOM 元素的基本流程。通常这是通过指令完成的,在这种情况下这可能也是您需要的。
我的模板中有一个指令。效果很好:
<ul class="activity-stream">
<my-activity-stream-item ng-repeat="activity in vm.activities" activity="activity"></my-activity-stream-item>
</ul>
我基本上想在该模板中包含与传单地图中的弹出窗口相同的 HTML,但我不知道如何在代码中创建它。这是我尝试过的:
for (i = 0; i < activities.length; i++) {
var activity = activities[i];
var marker = L.marker([activity.location.lat, activity.location.lng]);
marker.type = activity.type;
marker.bindPopup( '<my-activity-stream-item activity="activity"></my-activity-stream-item>' );
marker.addTo( map );
}
我真的没想到它会起作用,我觉得我必须以某种方式通过范围...但我完全不知道该怎么做。
var app = angular.module('myPortal');
app.factory('TemplateService', TemplateService);
app.directive('myActivityStreamItem', myActivityStreamItem);
function myActivityStreamItem( $compile, TemplateService ) {
return {
restrict: 'E',
link: linker,
transclude: true,
scope: {
activity: '='
}
};
function linker(scope, element, attrs) {
scope.rootDirectory = 'images/';
TemplateService.getTemplate( 'activity-' + scope.activity.type ).then(function(response) {
element.html( response.data );
$compile(element.contents())(scope);
});
}
}
function TemplateService( $http ) {
return {
getTemplate: getTemplate
};
function getTemplate( templateName ) {
return $http.get('/templates/' + templateName + '.html');
}
}
(注意 - 我只使用 Angular 大约一个星期,所以如果您认为我做错了,请告诉我)
编辑: 我采纳了 Chandermani 的建议并将指令切换为 ngInclude
:
<ul class="activity-stream">
<li ng-repeat="activity in vm.activities" ng-include="'/templates/activity-' + activity.type + '.html'"></li>
</ul>
这太棒了!我还尝试使用 Josh 的建议来编译 JavaScript 中的 HTML,但是我还没有完成...
var link = $compile('<li ng-include="\'/templates/activity-' + activity.type + '.html\'"></li>');
var newScope = $rootScope.$new();
newScope.activity = activity;
var html = link( newScope );
marker.bindPopup( html[0] );
这会导致出现弹出窗口,但弹出窗口中包含的 HTML 是一条评论:<!-- ngInclude: '/templates/activity-incident.html' -->
我是否必须以某种方式将它传递给 li
中的 activity?
编辑 2: 知道了!如 Issue #4505 中所述,您需要将代码段包裹在某些东西中,所以我将 ngInclude
包裹在 div
:
var link = $compile( '<div><ng-include src="\'/templates/activity-incident.html\'"></ng-include></div>' );
不确定我是否理解你的问题,但你可以做的是使用 ng-include
指令,它可以使用模板表达式来动态加载模板。类似于:
<ul class="activity-stream">
<li ng-repeat="activity in vm.activities" ng-include="'/templates/activity-' + activity.type + '.html'"></li>
</ul>
您可能不需要此处的指令。
任何时候你想添加原始 HTML 到页面并让 Angular 处理它,你需要使用 $compile
服务。
在模板上调用 $compile
将 return 一个链接函数,然后可用于将范围对象绑定到。
var link = $compile('<span>{{someObj}}</span>');
将该函数链接到 scope
对象将生成一个元素,然后可以将其附加到 DOM。
//Or the scope provided by a directive, etc...
var newScope = $rootScope.$new();
var elem = link(newScope);
//Could also be the element provided by directive
$('someSelector').append(elem);
这是您需要能够告诉 Angular 处理您的 DOM 元素的基本流程。通常这是通过指令完成的,在这种情况下这可能也是您需要的。