5

Being new to Angularjs, I need a bit of help with this issue. I am attempting to add ng-click="getGallery(57)" to a modal tab. Adding via jQuery is not the issue, however I realize when I do this, Angular is not compiling the newly added ng-click. I have a simple controller

function imageGalleryCtrl ($scope, $http) {

    //get gallery info on click
    $scope.getGallery = function(id)
    {
        $http.post('/beta/images/get_images',{'id': id}).success(function(data)
    {
        $scope.images = data.thisGal_images;
        $scope.images.galID = id;
    });
    };

}

I add the ng-click to the element with jQuery

//Edit image tab to use angularjs
$('#image_edit a').attr('ng-click','getGallery(' + settings.id + ')');

How do I force Angular to compile this newly added ng-click?

Thanks!

HTML Modal:

This is the modal that is called when the gallery name is clicked.

<div class="modal fade hide modal-creator" id="imageUploader" tabindex="-1" data-focus-on="input:first">
    <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal"></button>
        <h3>Create New Gallery</h3>
    </div>
    <div class="modal-body">
            <ul id="myTab" class="nav nav-tabs">
                <li id="image_home" class="">
                    <a href="#home" data-toggle="tab">Home</a>
                </li>
                <li id="image_upload" class="">
                    <a href="#upload" data-toggle="tab">Upload Image Gallery</a>
                </li>
                <li id="image_edit" class="">
                    <a href="#edit" data-toggle="tab">Edit Image Gallery</a>
                </li>
            </ul>

            <div id="myTabContent" class="tab-content">

                <div class="tab-pane fade in" id="home">
                    <?php include('create.php'); ?>
                </div>

                <div class="tab-pane fade" id="upload">
                    <?php include('upload.php'); ?>
                </div>

                <div class="tab-pane fade" id="edit">
                    <div class="span9">
                <ul id="imageSort" class="gallery-container">
                <li ng-repeat="image in images">
                <img ng-src="http://images.onlinealbumproofing.com/imageGallery/{{image.galleryID}}/{{image.imageName}}" alt="">
                {{image.orgName}}
                </li>
                 </ul>
               </div><!-- /span9 -->
                </div><!-- /row -->
                </div>

            </div>

    </div><!-- /modal-body -->

    <div class="modal-footer">
        <a href="javascript:;" class="btn" data-dismiss="modal">Close</a>
        <a href="javascript:;" id="next" class="btn btn-primary">Next</a>
    </div>

</div>

Update

So really attempting to do this the Angular way, and after some studies here is where I am at. The controller is the same as above and I have updated the tabs on the modal as follows.

<div class="modal-body">
            <ul id="myTab" class="nav nav-tabs">
                <li id="image_home" class="">
                    <a href="#home" data-toggle="tab">Home</a>
                </li>
                <li id="image_upload" class="">
                    <a href="#upload" data-toggle="tab">Upload Image Gallery</a>
                </li>
                <li id="image_edit" class="">
                    <a ng-click="getGallery(57)" href="#edit" data-toggle="tab">Edit Image Gallery</a>
                </li>
            </ul>

If I hard code the ng-click as above, the tab updates as expected. What I am trying to make happen, is when the modal is called, (#image_edit a) gets a defined ng-click="getGallery(id). I need to tell Angular to look at the ng-click again for the id.

4
  • 2
    Why do you need to use jQuery to do this can you show your HTML code where you are putting the image_edit links if it's in an ng-repeat you can just bind to the property on the returned element, if it's not present in the original data you can add it to the data in your response handler or using an interceptor. It's generally a bad thing to manipulate the DOM outside of directives which are run through the $compile service. Commented Jul 24, 2013 at 15:49
  • Thanks @shaunhusain. The ng-click is being added to the modal, depending on which gallery is clicked. Honestly I'm using jQuery as a crutch as I am still working on Angular. Commented Jul 24, 2013 at 16:03
  • No problem, thx for filling in some details, one more thing I think is missing is where do you define settings.id and is it available by the time the response for the $http.post call above returns? Commented Jul 24, 2013 at 16:34
  • Yes the settings.id is available onclick of the specific gallery Commented Jul 24, 2013 at 16:38

2 Answers 2

19

Although I too think that you should try and find another approach, the answer to your question

How do I force Angular to compile this newly added ng-click?

is

// remove and reinsert the element to force angular
// to forget about the current element
$('#button1').replaceWith($('#button1'));

// change ng-click
$('#button1').attr('ng-click','exec2()');

// compile the element
$compile($('#button1'))($scope);

See this working example: http://plnkr.co/edit/SgvQzaY0TyFHD1Mf0c3F?p=preview

Sign up to request clarification or add additional context in comments.

3 Comments

If you were to wrap this in a function within a service, how would you deal with $scope? As you can not inject $scope into a service!
You would have to pass the scope as an argument to that service. Something like this maybe: elementRecompilerService.RebindClick(parentElement, '#button1', $scope)
if $('#button1') has jquery event listeners would they all get wiped in the process?
2

Basically what I'm getting at is you want to probably make this happen:

<ul id="imageSort" class="gallery-container">
    <li ng-repeat="image in images">
        <img
            ng-src="http://images.onlinealbumproofing.com/imageGallery/{{image.galleryID}}/{{image.imageName}}"
            alt=""
            ng-click="getGallery(image.galleryID)"
            >
        {{image.orgName}}
    </li>
</ul>

The problem is I'm unsure of the relationship between the settings.id and the galleryID for a particular image. If you can set up this relationship in the data so it just automatically binds you're in better shape.

3 Comments

the galleryID and the settings.id are the same. When I call the modal everything is fine and here is where my question is a bit unclear, sorry. The tab prior to edit, allows to upload more images. So if I click on the edit tab after uploading a new image, I need to call the $scope.getGallery again so that I have the updated list of images.
Ah okay so if you have two different controllers and you want to communicate between them you can either use isolate scope, use events, or use a service to communicate between them and keep things up to date when a function is called. All three solutions are acceptable but can work better or worse depending on your scenario. This will be about the 20th time I've linked this: youtube.com/watch?v=ZhfUv0spHCY it's a bit long but gives great coverage for someone who's intermediate.
Personally I've mostly relied on services so far just because it's the first method I really learned within AngularJS to handle communicating between controllers (and generally I'm doing $http calls I want to share the data between where services make lots of sense). In some cases though using events $on $emit $broadcast or using isolate scope for directives (scope:{bound:"=",pexpress:"&", str:"@"}) good vids on that and other things here: egghead.io Also coming from an AS3 background I know events can get out of control.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.