4

I'm trying to access image src with controller to save it, but can not figure out how to do it.

My template:

    <img data-ng-model="book.image"
         style="width: 300px; height: 200px;"
         ng-src="data:image/png;base64,iVBORw0K...SuQmCC">
    <a data-ng-click="save(book)" class="btn">Submit</a>

My controller:

    controller('BookEditController', [ '$scope', '$meteor', function ($scope, $meteor) {
        $scope.save = function (book) {
            if (typeof book == 'object') {
                var books = $meteor("books");
                var id = books.insert(book);
            }
        };
    }])
4
  • Will you have multiple of these images? Commented Jun 13, 2013 at 18:24
  • Only one base64 encoded image. Commented Jun 13, 2013 at 18:40
  • How are you setting the ng-src is that static data or is it part of a ng-repeat or? Commented Jun 13, 2013 at 18:42
  • I'm loading it dinamically from input[file] with onchange event (it's my directive) More detailed html template code: pastebin.com/BG2Ntjam Commented Jun 13, 2013 at 19:00

2 Answers 2

5

One option is using a directive and applying a method called save to it which would handle the src attribute found on the image tag.
JS

var app = angular.module('myApp', []);
app.directive('saveImage', function () {
    return {
        transclude: true,
        link: function (s, e, a, c) {
            s.save=function(){
                alert(a.src);
            };
         }
    };
});

HTML

<div >
    <img save-image style="width: 300px; height: 200px;" src="http://placehold.it/350x150"> <a ng-click="save()" class="btn">Submit</a>

</div>

This is the code implemented in jsfiddle.

Another option is to isolate the scope to a controller but still apply the image to it instead of a function.

JS

var app = angular.module('myApp', []);
app.directive('saveImage', function () {
    return {
        transclude: true,
        link: function (s, e, a, c) {
            s.image = a.src;

        }
    };
});

function cntl($scope) {
    $scope.save = function (img) {
        alert($scope.image || 'no image');
    }
}

HTML

<div ng-controller='cntl'>
    <img save-image style="width: 300px; height: 200px;" src="http://placehold.it/350x150"> <a ng-click="save()" class="btn">Submit</a>

</div>

Notice the added ng-controller="cntl".

This is the JSfiddle for that one.

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

3 Comments

I have a habit of working with DOM directly in your scripts, so now I'm not so easy to be retrained. Thank you for your very detailed answer. I'll try to implement one of your options.
@Serg No problem! The second example does a check to make sure the $scope.image exists before doing anything with it.
slightly transformed your example, that the src attribute becomes a partof the book object: jsfiddle.net/6mkUV
1

There's probably a better way to do this... pass $event to your controller function

<a data-ng-click="save(book, $event)" class="btn">Submit</a>

and then use traversal methods to find the img tag and its src attr:

$scope.save = function (book, ev) {
    console.log(angular.element(ev.srcElement).parent().find('img')[0].src);
    ...

Update: the better way is to create a directive (like @mitch did), but I would use = binding in an isolate scope to update a src property in the parent scope. (The = makes it clear that the directive may alter the scope. I think this is better than having a directive add a method or a property to the controller's scope "behind the scenes".)

<div ng-controller="MyCtrl">
    <img save-image book="book1" src="http://placehold.it/350x150" >
    <a href="" ng-click="save(book1)">Submit</a>
</div>

function MyCtrl($scope) {
    $scope.book1 = {title: "book1" };  // src will be added by directive
    $scope.save = function(book) {
        alert(book.title + ' ' + book.src);
    }
}
app.directive('saveImage', function () {
    return {
        scope: { book: '=' },
        link: function (s, e, a, c) {
            s.book.src = a.src;
        }
    };
});

Plunker

3 Comments

The only thing I would comment on is putting any DOM manipulation in the controller isn't considered a good practice. Look at the section "Using Controllers Correctly" on docs.angularjs.org/guide/dev_guide.mvc.understanding_controller.
Mark Rajcok, I wanted to find an elegant and simple solution. But your solution is working. Mitch, maybe there are solution with mirroring src attribute into hidden input value(with directive or something like that)? Or it is not the right decision?
Thanks @mitch, I was being lazy. I should have mentioned that even examining the DOM structure in the controller is frowned upon. I like your answer (+1), but I would use an isolate scope with =, as shown in my updated answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.