【发布时间】:2017-08-15 08:23:59
【问题描述】:
由于我们缺乏使用 AngularJS 进行开发的专业知识,我们在开发过程中遇到了另一个障碍。
我们正在开发一个 Angular/Web API 应用程序,其中我们的页面仅包含一个交互式 SVG 图,当用户将鼠标悬停在 Angular 指令中的特定 SVG 标记上时显示数据。
应用程序中目前有两个自定义指令。
- 指令一 - 将 SVG 文件加载到网页中
- 指令二 - 添加 SVG 元素悬停事件/数据过滤器
指令一:
//directive loads SVG into DOM
angular.module('FFPA').directive('svgFloorplan', ['$compile', function ($compile) {
return {
restrict: 'A',
templateUrl: 'test.svg',
link: function (scope, element, attrs) {
var groups = element[0].querySelectorAll("g[id^='f3']")
angular.forEach(groups, function (g,key) {
var cubeElement = angular.element(g);
//Wrap the cube DOM element as an Angular jqLite element.
cubeElement.attr("cubehvr", "");
$compile(cubeElement)(scope);
})
}
}
}]);
SVG 图包含具有唯一标识符的标签,即:
<g id="f3s362c12"></g>
指令二从与每个 SVG 标签 ID 对应的注入服务加载 JSON 数据。
//filters json based on hover item
dataService.getData().then(function(data) {
thisData = data.filter(function (d) {
return d.seatId.trim() === groupId
});
如上所示,指令二还添加了一个悬停事件函数,根据悬停的标签过滤 JSON 数据。
IE:如果用户将鼠标悬停在 上,指令中的过滤器将返回此 JSON 记录:
{"Id":1,
"empNum":null,
"fName":" Bun E.",
"lName":"Carlos",
...
"seatId":"f3s362c12 ",
"floor":3,
"section":"313 ",
"seat":"12 "}
指令二:
//SVG hover directive/filter match json to svg
angular.module("FFPA").directive('cubehvr', ['$compile', 'dataService', function ($compile, dataService) {
return {
restrict: 'A',
scope: true,
link: function (scope, element, attrs) {
//id of group
scope.elementId = element.attr("id");
//alert(scope.elementId);
var thisData;
//function call
scope.cubeHover = function () {
//groupId is the id of the element hovered over.
var groupId = scope.elementId;
//filters json based on hover item
dataService.getData().then(function(data) {
thisData = data.filter(function (d) {
return d.seatId.trim() === groupId
});
//return data.seatId === groupId
scope.gData = thisData[0];
alert(thisData[0].fName + " " + thisData[0].lName + " " + thisData[0].deptId);
});
//after we get a match, we need to display a tooltip with save/cancel buttons.
$scope.empData = $scope.gData;
};
element.attr("ng-mouseover", "cubeHover()");
element.removeAttr("cubehvr");
$compile(element)(scope);
}
//,
//controller: function($scope, $element){
// $scope.empData = $scope.gData;
//}
}
}]);
我们现在遇到的问题是(除了拥有最少的 Angular 经验和面临一个独特而困难的实现问题之外)是我们正在尝试实现一种使用 div 标签和 Angular 范围变量创建工具顶的方法可以在用户将鼠标悬停在 SVG 标记元素上时显示(而不是在下面的 Plunker POC 链接中演示的 Javascript 警报)。
由于数据是由指令驱动的,并且指令已经将“cubehvr”作为参数:
angular.module("FFPA").directive('*cubehvr*', ['$compile', 'dataService', function ($compile, dataService)
我们被困住了,因为我们不知道如何设置 HTML 页面范围指令或变量,就像我们的第二个指令这样:
<div uib-popover="Last Name: {{empData.lName}}"
popover-trigger="'mouseenter'"
type="div"
class="btn btn-default">Tooltip
</div>
或者说这么简单:
<div emp-info></div>
div 工具提示将包含调用 Web API 更新功能的 html 按钮。
我们在这里有一个按比例缩小的 POC Plunk:
还在考虑将 Angular Bootstrap UI 用于工具:
希望这是有道理的。
【问题讨论】:
-
我不确定我是否理解您想要做什么。基本上,您想找到一种方法来跨指令共享
scope变量值,对吗? -
从我对 Angular 的有限理解来看,我认为这是正确的。在第二个指令中,我们正在考虑是否可以根据用户悬停在的项目访问或设置 div 标签中的值,我们可以创建一个 div toollip 来显示给用户。我们目前不知道如何做到这一点。我希望这能回答你的问题。谢谢
-
是的,我认为这是有道理的。因此,您的代码遇到的第一个问题是您尝试使用
$scope,但没有在任何地方注入它——尽管您确实有scope。除非您想使用隔离范围获得超级花哨,否则如果您想在指令之间传递值,您可以查看将它们绑定到$rootScope或使用工厂或服务传递它们。老实说,如果你们对 Angular 的经验有限,那就让它超级简单。不要试图完美地做每一件事,而是让它发挥作用,当你理解它时再回来。 -
感谢您的回复。你有一个例子说明我们如何在当前问题的背景下做到这一点?尝试将作用域注入:angular.module("FFPA").directive('cubehvr', ['$scope', '$compile', 'dataService', function ($scope, $compile, dataService) {}。错误:错误:[$injector:unpr] 未知提供者:$scopeProvider
-
是的,如果使用
$scope是您想要做的事情,我想知道。根据您想要执行的操作,您可以为两个指令声明相同的controller并使用它来访问共享范围。老实说,我仍然不是 100% 清楚你想要什么。话虽如此,为了传递数据,我会考虑使用隔离范围或仅使用服务/工厂在指令之间传递值。
标签: javascript angularjs svg angularjs-directive angularjs-scope