javascript - AngularJS 自定义指令访问范围数据

标签 javascript angularjs svg angularjs-directive

我们是 AngularJS 的新手,但正在尝试从 Angular 中的自定义指令显示一些 html 工具提示,并且由于这项技术的新手正在努力为这个问题找到合适的解决方案。

我们有一个使用 Angular+Web API 运行的解决方案版本,但发现鼠标悬停事件和 CRUD 功能属于指令而不是 Controller ,因此我们将其取出并重新构建。

目前在 Plunker POC,我们有:

  1. 加载了一个非常小的 SVG 文件。
  2. 加载了一个小的 json 数据文件。
  3. 为每个 SVG 元素附加一个自定义指令悬停事件
  4. 当鼠标悬停在特定元素上时,将使用元素 ID 执行 alert()。

SVG 示例:

<g id="f3s362c16">
<rect x="577.5" y="533.2" fill="none" width="22.2" height="25.7"/>
<polyline fill="none" stroke="#CEDEED" stroke-width="0.6468" stroke-miterlimit="10" points="590.4,559 577.5,559 577.5,533.2 
    599.5,533.2 599.5,550   "/>
<text transform="matrix(1 0 0 1 590.9561 557.4941)" font-family="arial, sans-serif" font-size="5.1408">362.16</text>

Json 示例:

{"Id":1,"empNum":null,"fName":" Bun E.","lName":"Carlos","refacName":null,"deptId":"Drums","divisionId":null,"jobDesc":"Drummer","seatTypeId":1,"officeCode":null,"phone":null,"seatId":"f3s362c12 ","oldSeatId":null,"floor":3,"section":"313 ","seat":"12 "}

我们有一个在 html 文件中定义的 json 的范围变量:

{{ **empData** }}

Controller 文件数据加载:

 var onLoadComplete = function (response) {
   $scope.**empData** = response.data;
 }

 //error
 var onError = function(reason) {
   $scope.error = "Could not get the data";
 }

 //get data
 $http.get('data.json')
    .then(onLoadComplete, onError);

加载 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);
        })
      }
    }
}]);

立方体悬停指令:

angular.module("FFPA").directive('cubehvr', ['$compile', function ($compile) {
return {
    restrict: 'A',
    scope: true,
    empData: "=",

    link: function (scope, element, attrs) {

        //id of group 
        scope.elementId = element.attr("id");

        //function call from line 63
        scope.cubeHover = function () {

            //groupId is the id of the element hovered over.
            var groupId = scope.elementId;

            alert(scope.elementId);
            //Here need to get access to scope empdata json to filter and 
            //match to the cube #.
            //IE: If I hover over 362.12, return json data for
            //{"Id":1,"empNum":null,"fName":" Bun E.","lName":"Carlos","refacName":null,"deptId":"Drums","divisionId":null,"jobDesc":"Drummer","seatTypeId":1,"officeCode":null,"phone":null,"seatId":"f3s362c12 ","oldSeatId":null,"floor":3,"section":"313 ","seat":"12 "}
            //since we don't have access to the empData scope variable, cannot run filter.
            var thisData = empData.filter(function (d) {
              return d.seatId.trim() === groupId
            });
            //after we get a match, we need to display a tooltip with save/cancel buttons.


        };
        element.attr("ng-mouseover", "cubeHover()");
        element.removeAttr("cubehvr");
        $compile(element)(scope);
    }
}
}]);

我们收到特定立方体悬停的警报,但我认为我们需要访问页面范围变量来执行过滤器:

var thisData = empData.filter(function (d) {
              return d.seatId.trim() === groupId

});

一旦我们得到匹配,我认为我们应该能够将 html 附加到我们的 div 标签并显示它:

   <div class="tooltip"></div>

Angular :

tooltip.html("Name: " + thisData[0].fName + " " + 
thisData[0].lName  + "<br>Role: " + 
thisData[0].jobDesc + "<br>Extension: " + 
thisData[0].phone)//+ "<br>Avatar: <img src=" + thisData[0].Avatar + ">")
.style("top", (d3.event.pageY + 15) + "px").style("left", (d3.event.pageX + 0) + "px")
.style("visibility", "visible");

此时,我们不确定如何在悬停(第二个)指令中获取 View /页面范围变量 {{empData}},因为我们已经将指令传递给 cubeHvr:

angular.module("FFPA").directive('cubehvr', ['$compile', function ($compile)       {...}      

提前感谢您在这里给我们的任何指导。

最佳答案

定义一个服务如下代码

angular.module('FFPA')
.service('dataService', function () {
    this.getData = function(){
        return $http.get('data.json').then(function(){
             return response.data;
           }, function(){
               return {err:"Could not get the data"};
           }
        );
    }
});

然后将其注入(inject)任何指令、 Controller 、组件或服务。

angular.module("FFPA").directive('cubehvr', ['$compile','dataService', function ($compile,dataService) {
return {
    restrict: 'A',
    scope: true,
    link: function (scope, element, attrs) {

        dataService.getData().then(function(data){
            scope.emData=data;
        })

关于javascript - AngularJS 自定义指令访问范围数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42751632/

相关文章:

javascript - 我可以在 useEffect 之外声明变量吗? react 钩子(Hook)

javascript - Java:如何将值从 javascript 设置到 wicket 组件文本字段

javascript - 观察 AngularJS 指令中函数的值

c# - SVG:如何为文本创建自调整容器

javascript - 如何使用 jQuery/JavaScript 对 svg 路径进行动画处理?

javascript - 如何使用backbone.js划分JSON集合结果

javascript - 将单击的图像保存在 var 中并将其设置为随后显示的新 div 的背景 - 如何?

javascript - 将 jquery 插件集成到 angular js 中

javascript - 返回一个新函数而不是工厂中的对象

html - 为什么我的 svg 上有一个 100% 的垂直滚动条?