Myeong-jae Kim Myeong-jae Kim - 4 months ago 19
AngularJS Question

scope issue with ng-view, parent controller, custom directive

I'm so confused about my situation. Let me briefly introduce my situation.

HTML structure. (It's just structure, full HTML is more than that but there is no any other controller except "pageController")

<body ng-app="app">
<div id="wrapper" ng-controller="pageController">
<div id="menu">
<a>.........</a>
</div>
<div id="mainView">
<ng-view></ng-view>
</div>
</div>
</body>


Of course, I properly set router.

var app = angular.module("app", ["ngRoute"])
.config(function($routeProvider){
$routeProvider
.when("/about", {
templateUrl: "about.html"
})
.when("/summary", {
templateUrl: "summary.html"
})
.when("/company", {
templateUrl: "company.html"
})
.when("/remote", {
templateUrl: "remote.html"
})
.when("/personal", {
templateUrl: "personal.html"
})
.when("/academic", {
templateUrl: "academic.html"
})
.otherwise({
redirectTo : "/about"
});
});


I didn't set any controller now. I put each controller as "pageController" before but I removed now because I think pageController will be automatically inherited as long as pageController is in parent element.

And I made custom directive.

app.directive('imageLoader', function(){
return{
restrict:'A',
link:function(scope, elem, attrs){
elem.bind('click', function(){
var fileName = "img/portfolioImages/" + attrs.ori;
scope.$parent.$parent.modalImgSrc = fileName;
scope.$parent.$parent.isModalOpen = true;

scope.$parent.$parent.$digest();
});
}
};
});


In injected html in ng-view, there is no any other controller, but it dynamically generate
<img>
tag like below

<div class="project-image-div">
<img image-loader ng-repeat="aImgSrc in remoteImageFiles[0]"
data-ori='{{aImgSrc}}' class='project-img-s'
ng-src='img/portfolioImages/{{aImgSrc.substring(0,aImgSrc.lastIndexOf(".")) + "_s" + aImgSrc.substr(aImgSrc.lastIndexOf("."), 4)}}'>
</div>


remoteImageFiles[0] is json object saved in pageController scope. And these dynamically added img tags are completely fine.

THE PROBLEM

As you can see in
<img>
tag, I am using custom directive image-loader. In directive code, I expected "scope" is same scope as pageController as long as there is no any other controller inside ng-view and I didn't give any option for scope in the custom directive.

But I printed scope object in console, I can access pageController scope object as parent of parent... WHY?????

scope.$parent.$parent.modalImgSrc = fileName;
scope.$parent.$parent.isModalOpen = true;

scope.$parent.$parent.$digest();


Thank you for reading my long post... please help... I am spending 2 days for this..

You can see full code in my personal web site. I am noob to angularJS. I am converting JQuery version of site to pure angularJS version to learn AngularJS.. It's in progress.

AngularJS version..(converting now)
http://bear-mj.com/MJKim

JQuery version..(all working)
http://bear-mj.com/MJKimJQuery/

Lex Lex
Answer

You have 3 levels of scope created. Remember, both ng-repeat and ng-view create a new scope. In this area of your app - inside the directive:

  1. scope is the ng-repeat scope
  2. scope.$parent is the ng-view scope
  3. scope.$parent.$parent is the pageController scope