简体   繁体   中英

Angular bindings: controller not updating with directive

so I've been following along with this tutorial on how to make an interactive SVG map with Angular. i'm at the point now where i'm trying to strike out on my own and get it to do stuff I want.

https://medium.com/@tweededbadger/tutorial-dynamic-data-driven-svg-map-with-angularjs-b112fdec421d#.2eprazbg6

Specifically, I want clicking on an area of the map to bring up info about that area in a sidebar. To start with, displaying the name of the area clicked.

However even form looking at 10+ tutorials online, I can't seem to figure out what isn't working. The variable I'm trying to update is $scope.selected in the controller , from what I can see I've done the binding properly in the directive scope, not sure where I'm going wrong. Been trying different stuff for hours but getitng nowhere, any help would be appreciated. Thanks!

angular.module('SvgMapApp', ['ngRoute'])


.controller('MainCtrl', ['$scope', function ($scope) {
    $scope.wardList = ["St. Anthony's Ground Floor", "Endoscopy", "St. Laurence's Corridor", "Sacred Heart Ward", "Physiotherapy"];
    $scope.selected = {name: "none"};
}]);


angular.module('SvgMapApp').directive('svgMap', ['$compile', function ($compile) {
return {
    restrict: 'A',
    templateUrl: 'img/GFloorMk1.svg',
    link: function (scope, element, attrs) {
        var areas = element[0].querySelectorAll('.ward');
        angular.forEach(areas, function (path, key) {
            var areaElement = angular.element(path);
            areaElement.attr("area", "");
            $compile(areaElement)(scope);
        })      
    }
}
}]);    

angular.module('SvgMapApp').directive('area', ['$compile', function ($compile) {
return {
    restrict: 'A',
    scope: {
        selected: '=',
    },
    link: function (scope, element, attrs) {
        scope.elementId = element.attr("id");
        scope.areaClick = function () {
            scope.selected = scope.elementId;
           alert(scope.elementId);
        };
        element.attr("ng-click", "areaClick()");
        element.removeAttr("area");
        $compile(element)(scope);
    }
}
}]);

Here is the main index page. The view displays the SVG for the current floor of the map being displayed.

<html>
<head lang="en">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Data Responsive SVG Map</title>
<link rel="stylesheet" href="css/bootstrap.min.css"/>
<link rel="stylesheet" href="css/main.css"/>
</head>
<body ng-app="SvgMapApp" ng-controller="MainCtrl">

<div class="container">

<div class="row">
  <div class="col-md-4"><a href="#/gfloor">Ground Floor</a></div>
  <div class="col-md-4"><a href="#/1stfloor">First Floor</a></div>
  <div class="col-md-4"><a href="#/2ndfloor">Second Floor</a></div>
</div>
<div class="row">
    <div class="col-md-10">
        <div ng-view></div>
    </div>  
    <div class="col-md-2">
        <div class="row">
            <h2>Ward Name</h2>
            <h2> {{ selected.name }}</h2>
    </div>
</div>
</div>

<script src="js/angular.js"></script>
<script src="js/angular-route.js"></script>
<script src="js/controllers.js"></script>
<script src="js/directives.js"></script>
<script src="js/filters.js"></script>
</body>
</html>

And in the gfloor.html partial, this is how the directive is displayed in the view.

<div svg-map
class = "directive",
selected = "selected">

I fixed this by adding

                    element[0].parentNode.appendChild(element[0]);  

To the area directive like

        scope.areaClick = function () {
           scope.selected = scope.elementId;
           element[0].parentNode.appendChild(element[0]);   
    };

and also

 areaElement.attr("selected", "selected");

to the svgMap directive.

I also had to take the directive divs themselves out of the views partials to work, instead having it directly on the index.html page.

Index.html:

    <!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Data Responsive SVG Map</title>
    <link rel="stylesheet" href="css/bootstrap.min.css"/>
    <link rel="stylesheet" href="css/main.css"/>
</head>
<body ng-app="SvgMapApp" ng-controller="MainCtrl">
    <div class="row">

        <div class="col-md-8">
                <div svg-map></div>
                <!--<div ng-view></div>-->          <--would love this to work
        </div>
        <div class="col-md-4">
                <h2>Click for Data</h2>
                <p>
                    <button ng-click="createDummyData()" class="btn btn-block btn-default">Create Dummy Data</button>
                </p>
                <h1>Selected Ward:</h1>
                <h2> {{ selected.name }} </h2>
                  /.. more stuff here../                
                <h1> Summary of ward: </h1>
                <h2> {{ hoverArea }} </h2>
                <h2>(i.e. the one being moused over)</h2>
             /.. irrelevant stuff../
        </div>      
    </div>

<script src="js/angular.js"></script>
<script src="js/angular-route.js"></script>
<script src="js/controllers.js"></script>
<script src="js/directives.js"></script>
<script src="js/filters.js"></script>
</body>
</html>

I'd like if someone could drop an explanation of what I actually did re the childNode update thing... and even moreso if someone could explain why the directives don't update the scope while inside a view partial in this situation. The partial displays in the view fine and the svg displays fine with expected behaviours, it just doesn't update the scope variable. Partial is just this:

gfloor.html:

<div svg-map></div>

So I expected it to work the same tbh! I'm sure it's something else stupid I've missed, and it doesn't matter too much as I can just copy and pate to make identical pages, I'm just curious for my own knowledge if there's someway to fix it so the directive in the view behabves the same as the directive directly on the index page.

Cheers!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM