1

I have a list of images. One next to the other. I'm trying to capture which image was clicked, populate a modal div and show it.

Markup

    <section class="portfolio-grid column small-12" ng-controller="PortfolioCtrl">
    <ul class="small-block-grid-2 medium-block-grid-4">
        <li ng-repeat="portfolio in portfolios">
            <a ng-click="showModal($index)" title="">
                <img ng-src="{{portfolio.thumb}}" alt="">
                <div class="details">
                    <h4>{{portfolio.name}}</h4>
                </div>
            </a>
        </li>
    </ul>
</section>
======== Some Other HTML ========
<div class="popup" ng-controller="ModalCtrl">{{info}}</div>

At first it shows {"name":"Test"}, which is alright. After I click it does not get updated even though I believe I am changing the variable inside the service when I click.

Controller

app.controller("PortfolioCtrl", function($scope, $rootScope, PortfolioService, ModalService){
    $scope.portfolios = PortfolioService.list();
    $scope.showModal = function(index){
        ModalService.setInfo($scope.portfolios[index]);
    }

});
app.controller("ModalCtrl", function($scope, ModalService){
    $scope.info = ModalService.getInfo();
});

Service

app.service('ModalService', function(){
    var modalInfo = {"name":"test"};

    this.setInfo = function(data){
        modalInfo = data;
    };
    this.getInfo = function(){
        return modalInfo;
    };

});

app.service('PortfolioService', function(){
    var portfolios = [
        {"name":"Project Name 1", "thumb":"http://placehold.it/480&text=1", "bigImg":"http://placehold.it/1000x500&text=1", "description":"Description text 1", "linkToLive": "#"},
        {"name":"Project Name 2", "thumb":"http://placehold.it/480&text=2", "bigImg":"http://placehold.it/1000x500&text=2", "description":"Description text 2", "linkToLive": "#"},
    ]

    this.list = function(){
        return portfolios;
    }

});

2 Answers2

0

You didn't insert dependecy injection ModalService in PortfolioCtrl controller

app.controller("PortfolioCtrl", function($scope, $rootScope, PortfolioService,ModalService ){
    $scope.portfolios = PortfolioService.list();
    $scope.showModal = function(index){
        ModalService.setInfo($scope.portfolios[index]);
    }

});
Ilya Dmitriev
  • 1,680
  • 1
  • 16
  • 22
0

Your ModalCtrl controller function is only called once, when the modal is encountered into the DOM. This means that $scope.info is set to the initial value returned by ModalService.getInfo() and never changed.

You could watch for changes of the value returned by getInfo:

app.controller("ModalCtrl", function($scope, ModalService){
    $scope.$watch(function() { return ModalService.getInfo(); }, function(){
        $scope.info = ModalService.getInfo();
    });    
});
Tibos
  • 27,507
  • 4
  • 50
  • 64
  • This works as expected. I wasn't aware of how exactly $watch worked. Now I get it. If ModalService.getInfo() changes, it will trigger the getInfo() function for the $scope.info. NICE! Thank you! – Fernando Claussen May 16 '15 at 06:20
  • $watch gets two functions - the first returns a value and the second is a callback to be executed when the value returned by the first changes. Read more in the documentation - https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watch – Tibos May 16 '15 at 06:22
  • What should I do if I want to init a jquery plugin after the content is changed? I have a directive for this popup. I need to call flexslider after the content is done populating. – Fernando Claussen May 16 '15 at 19:58
  • Oh, nevermind. I got it working with this on my directive: link: function(scope, element, attr) { scope.$watch(function(){ return element.html(); }, function(){ element.find('.flexslider').flexslider({ animation: "slide", }); }); } – Fernando Claussen May 16 '15 at 20:10