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

时间:2017-03-12 18:49:40

标签: javascript angularjs svg angularjs-directive

我们是AngularJS的新手,但他们正试图在Angular的自定义指令中显示一些html工具提示,因为这项技术的新手很难为这个问题找到合适的解决方案。

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

目前在Plunker POC中,我们有:

  1. 加载了一个非常小的SVG文件。
  2. 加载了一个小的json数据文件。
  3. 对于每个SVG元素,附加了自定义指令悬停事件
  4. 当悬停特定元素时,将使用元素id执行alert()。
  5. 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** }}
    

    控制器文件数据加载:

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

    Cube Hover指令:

    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>
    

    角:

    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");
    

    此时,我们还不确定如何在hover(2nd)指令中获取视图/页面范围变量{{empData}},因为我们已经通过了cubeHvr指令:

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

    提前感谢您在此提供的任何指示。

1 个答案:

答案 0 :(得分:1)

将服务定义为以下代码

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"};
           }
        );
    }
});

然后将其注入任何指令,控制器,组件或服务。

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;
        })