我们在电子浏览器中有此AngularJS SP应用程序(智能镜像),该应用程序具有用户可创建的扩展。
扩展名是使用角度指令的html小片段 并使用控制器和服务。
要安装扩展程序,必须编辑主页并为控制器和服务功能插入脚本标签,为HTML代码段插入<div ng-include= ...>
硬编码此单页应用程序效果很好。
但是我想向此应用程序(开源)添加功能以某种方式动态加载这些元素...
将标签添加到dom的工作原理,但未正确处理。 在运行脚本(来自插入的标签)之前处理HTML,并且当ng-include插入HTML代码段时,尚未定义控制器...
主体(带有在硬编码位置的扩展名被注释掉)
<body ng-controller="MirrorCtrl" ng-cloak>
<div class="top">
<div class="top-left">
<!-- <div ng-include="'plugins/datetime/index.html'"></div>
<div ng-include="'plugins/calendar/index.html'"></div> -->
</div>
<div class="top-right">
<!-- <div ng-include="'plugins/weather/index.html'"></div>
<div ng-include="'plugins/traffic/index.html'"></div>
<div ng-include="'plugins/stock/index.html'"></div>
<div ng-include="'plugins/tvshows/index.html'"></div>
<div ng-include="'plugins/ha-display/index.html'"></div> -->
</div>
</div>
...
...
<script src="filename.service"/>
<script src= filename.controller"/>
</body>
日历扩展html(插入页面的特定div区域)
<ul ng-controller="Calendar" class="calendar fade" ng-show="focus == 'default'" ng-class="config.calendar.showCalendarNames ? 'show-calendar-names' : ''">
<li class="event" ng-repeat="event in calendar" ng-class="(calendar[$index - 1].label != event.label) ? 'day-marker' : ''">
<div class="event-details">
<span class="day">
<span ng-bind="event.startName"></span>
<span ng-if="event.startName != event.endName"> - <span ng-bind="event.endName"></span></span>
</span>
<div class="details calendar-name" ng-bind="event.calendarName"></div>
<span class="summary" ng-bind="event.SUMMARY"></span>
<div class="details" ng-if="event.start.format('LT') != event.end.format('LT')">
<span ng-if="event.startName != event.endName"><span ng-bind="event.start.format('M/D')"></span> <span ng-bind="event.start.format('LT')"></span> - <span ng-bind="event.end.format('M/D')"></span> <span ng-bind="event.end.format('LT')"></span></span>
<span ng-if="event.startName == event.endName"><span ng-bind="event.start.format('LT')"></span> - <span ng-bind="event.end.format('LT')"></span></span>
</div>
<div class="details" ng-if="event.start.format('LT') == event.end.format('LT')">All day</div>
</div>
</li>
</ul>
日历扩展程序控制器(由html使用)
function Calendar($scope, $http, $interval, CalendarService) {
var getCalendar = function(){
CalendarService.getCalendarEvents().then(function () {
$scope.calendar = CalendarService.getFutureEvents();
}, function (error) {
console.log(error);
});
}
getCalendar();
$interval(getCalendar, config.calendar.refreshInterval * 60000 || 1800000)
}
console.log("registering calendar controller")
angular.module('SmartMirror')
.controller('Calendar', Calendar);
日历扩展服务(由控制器使用,在此讨论中已缩短)
(function () {
'use strict';
function CalendarService($window, $http, $q) {
...
...
return service;
}
console.log("registering calendar service")
angular.module('SmartMirror')
.factory('CalendarService', CalendarService);
} ());
,因此想要添加扩展名的用户必须创建这些文件, 并编辑主页HTML并将其插入
<div ng-include src="filename.html"></div>
在正确的位置,然后添加
<script src="filename.service" >
和
<script src="filename.controller">
在正确的位置和顺序上,需要在控制器之前完成服务, 控制器使用服务。
无论如何,添加代码很容易找到所有扩展并将元素动态地插入dom各自的位置...但是...
在硬编码中,脚本被添加到正文中的html之后
因此,我添加了一个新脚本(在加载页面时进行处理),该脚本查找并插入所有元素以在正确的位置支持扩展。
,然后脚本结束....(硬编码HTML中的最后一个),并且处理了HTML指令,并且没有加载或处理动态添加的脚本,因此找不到控制器。
我可以创建一个包含所有这些信息的临时HTML文件,然后加载THAT而不是动态加载,但是我认为解决此问题更好
我尝试创建自己的角度指令并将其编译,但是陷入循环
<divinc src="filename.service"></divinc>
作为divinc指令的子代,插入的div是正确的
angular.module('SmartMirror')
.directive("divincl", ["$compile" ,function($compile){
return {
priority: 100,
terminal: true,
compile: function(scope, element, attrs) {
var html = "<div ng-include=\"" + element['incl']+ "\" onload='function(){console.log(\'html loaded\')}'></div>"
var templateGoesHere = angular.element(document.getElementById(element['id']));
templateGoesHere.html(html);
//document.body.innerHTML='';
var v= $compile(templateGoesHere);
//scope.$apply();
return function linkFn(scope) {
v(scope) // Link compiled element to scope
}
}
}
}]);
有关如何解决此问题的建议。谢谢
答案 0 :(得分:0)
为了使angularjs 1.7应用程序能够动态加载扩展,有两种方法:
我建议您也不要忘记使用ng-include
,并尝试在应用程序的指令中添加<script></script>
。
首先,您需要重新了解如何启动angularjs应用程序。
angular.module
,angular.directive
,angular.value
,angular.config
,angular.run
...调用制作。这是声明步骤 MyApp
,并且在html中有一个带有ng-app="MyApp"
的DOM元素,则angularjs将在此DOM元素上自动运行angular.bootstrap()
以便启动{{1 }}。应用程序的MyApp
从此处开始。您无法在模块execution
中声明任何内容。其次,我认为模板中的MyApp
代码已被清理并按角度删除。另外,即使您执行了代码,由于<script></script>
已经完成,因此您不应该创建新的指令或注册新的服务,否则它将不起作用。
一个好方法是,当您加载插件时,您将:
declaration step
。MyPlugin1
<div ng-app="MyPlugin1"></div>
,这将使启动子应用程序成为可能。如果执行此操作,则可以运行子应用程序,但未传递参数。为了传递参数,您可以将模块angular.bootstrap
的代码放入函数中,以建立应用程序工厂。然后使用MyPlugin1
初始化应用。
例如:
app.value('param1', parameter1)
在指令调用function declarePlugin1(myParam1, myParam2) {
var app = angular.module('MyPlugin1', []);
// app.directive();
app.value('myParam1', myParam1);
app.value('myParam2', myParam2);
}
中,它将使用初始化值声明应用程序declarePlugin1("test", 42);
,然后MyPlugin1
告诉angularjs启动此应用程序。
您也可以传递回调,以便在两个应用程序之间进行通信。