AngularJS custom directives not working when using ng-include "Object #<Scope> has no method"

So I decided after much debate, to split my webpage into two parts, one for ie7 and another for ie8+. I have many

<!-- if lte ie7---> 

scattered around, and I just want to separate the html as much as possible. Sure it's heavier maintenance, but whatev.

So as I moved my html content from the main.html to submain.html, I noticed one of my custom directives wasn't working.

Note: All my javascript gets loaded AFTER I load the html content.

I have a directive called ng-map, where if this attribute appears on any div with an ID, it'd call mapquest to fill in the div with an interactive map. Currently this works.

However, if I move the directive:

<div ng-map id="map"></div>

out of main.html and place it into submain.html and add this in my main.html:

<div ng-include="'view/submain.html'">

it doesn't work, even though my submain.html loads properly.

It gives me the error: "Error: Object # has no method 'initMap'"

This is what my directive looks like:

mapapp.app.directive('ngMap', ['logger', '$http', function (logger, $http) {
    var directiveDefinitionObject = {
        restrict: 'A',
        controller: function link($scope, $element) {
            $scope.shouldMapLoadOnPageLoad = true;

            $scope.loadCodeAndMap =
                function () {
                    var key = {...};
                    var script = document.createElement('script');
                    script.type = 'text/javascript';
                    script.src = "http://www.mapquestapi.com/sdk/js/v7.0.s/mqa.toolkit.js?key=" + key;
                    document.body.appendChild(script);
                };
            $scope.loadCodeAndMap();
            $scope.initMap = function () {
               ...
            }
        }
    };
    return (directiveDefinitionObject);
}]);

Any help in understanding what is happening here is appreciated.

Answers


Okay figured it out, but I don't have complete understanding.

When I load up my html content, controller, and directives, I was able to call the $scope.initMap function located in my directive from a $watch on my controller.

So this worked:

controller:

$scope.$watch('blahData', function(newVal, oldVal) {
    $scope.initMap();
}

directive:

$scope.initMap = function() { .. }

however, when I change my html to load via ajax (which I assume that's what ng-include does to fetch the html from a location, you need to change the above logic.

So the previous html goes from this:

<html><head></head>
<body>
    <!-- Stuff -->        

    <div>Hello!</div>

    <!-- More Stuff --> 
</body></html>

to

<html><head></head>
<body>
    <!-- Stuff -->        

    <!-- Home.html has <div>Hello!</div> -->
    <div ng-include="'Template/Home.html'" />

    <!-- More Stuff --> 
</body></html>

Then the controller becomes something like this:

$scope.initMap = false; //not a function anymore
$scope.$watch('blahData', function(newVal, oldVal){
    $scope.initMap = !$scope.initMap;
}

and the directive becomes:

$scope.$watch('$scope.initMap', function() { ... }

So the directive now watches the data happening from the controller. Now, if your directive doesn't include scope: '=' for the directive options, then you have to access the controller scope as a parent:

$scope.$watch('$scope.$parent.initMap, function() { ... }

that's because scope: '=' binds the local $scope on the directive to the parent scope (the controller).


Need Your Help

Cast an array to pointer in function return

c++ function pointers return

I get a problem about pointer in C++. The code is:

How do I get Sitecore's home url?

c# asp.net sitecore

How do I just get http://www.mysite.com/en the main part of the Site homepage url without the item path? Ultimately, I want to append the Model.Url to