【发布时间】:2019-05-21 14:43:15
【问题描述】:
我们在电子浏览器中有这个 AngularJS SP 应用程序(智能镜像),它有用户可创建的扩展。
扩展是使用角度指令的 html 的小 sn-ps 并使用控制器和服务。
要安装扩展,必须编辑主页并为控制器和服务功能插入脚本标签,并为 HTML 的 sn-p 插入 <div ng-include= ...>
对这个单页应用进行硬编码效果很好。
但我想向这个应用程序(开源)添加功能,以某种方式动态加载这些元素......
将标签添加到 dom 有效,但未正确处理。 在运行脚本(来自插入的标签)之前处理 HTML,当 ng-include 插入 HTML sn-p 时,控制器尚未定义......
正文(硬编码位置的扩展名已被注释掉)
<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 文件并加载它而不是处理动态加载,但我认为最好解决这个问题
我尝试过创建自己的角度指令并编译它,但陷入了循环
<divinc src="filename.service"></divinc>
插入的 div 是正确的,作为 divinc 指令的子项
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
}
}
}
}]);
关于如何解决这个问题的建议.. 谢谢
【问题讨论】:
-
您要做的是嵌套的 angularjs 应用程序。这里有个问题:stackoverflow.com/questions/18184617/…。我使用 Martin Thurau 的评论使它起作用:这是他的示例:codepen.io/mthur/pen/QvaoQY。我个人使用这种系统来运行子应用程序,今晚会写一个完整的答案。
-
你看过我之前写的吗?你需要我写一个答案还是你认为这不是你需要的?
-
对不起,走了一整天......我创建了链接示例中的“插件”元素```我不知道你如何在 cmets 中格式化...用
code表示括号,但这不起作用上述代码 a[0].appendChild(ss) 将 div 树放在主应用程序 html 树的右侧元素中 var p = document.getElementById(plugin) angular.module(plugin, []); var e=angular.element(p) e.injector = function() { return false; } angular.bootstrap(e, [插件]);删除 e.injector(); `