简体   繁体   中英

Cannot access a variable inside controller in angular

I am trying to implement a Crop Plugin Library in my angular demo project. I have injected the required modules to my main module and successfully cropped a pic. But I don't know how to pass the base64 string to the controller. What I have tried so far is:

var myApp = angular.module('myModule', ['ngRoute', 'angular-img-cropper', 'app']);

myApp.config(function($routeProvider) {
        $routeProvider
            .when('/multiple',{
                    templateUrl: 'templates/multi.html',
                    controller: 'multiController',
                    controllerAs: 'multiCtrl'           
            })
});

myApp.controller('multiController', function ($scope,$rootScope) {
        var vm = this;
        vm.clickButton = function () {
            console.log("photo: "+vm.member_photo);
        };
});

HTML - templates/multi.html:

<h1>Multi page which has another controller inside</h1>
<div ng-controller="multiController">
    <div ng-controller="ImageCropperCtrl as ctrl">
    <input type="file" img-cropper-fileread image="cropper.sourceImage"   />
    <div>
      <canvas width="500" height="300" id="canvas" image-cropper image="cropper.sourceImage" cropped-image="cropper.croppedImage" crop-width="500" crop-height="200" min-width="100" min-height="50" keep-aspect="true" crop-area-bounds="bounds"></canvas>
    </div>
    <div>Cropped Image (Left: {{bounds.left}} Right: {{bounds.right}} Top: {{bounds.top}} Bottom: {{bounds.bottom}})</div>
    <div ng-show="cropper.croppedImage!=null"><img ng-model="member_photo1" ng-src="{{cropper.croppedImage}}" /></div>
        <textarea name="member_photo" ng-model="multiCtrl.member_photo" id="member_photo" class="form-control valid">{{cropper.croppedImage}}</textarea>
    </div>
  <button ng-controller="insideController" ng-click="multiCtrl.clickButton()">Console.log</button>
</div>

If I inspect the textarea the value is there but it is not shown inside the textarea and also the value cannot be accessed inside my controller. What am I doing wrong?

As @Taylor Buchanan has already pointed out there are multiple issues with your code. And I too recommend that you review Angular documentation and examples.

Apart from the issues that @Taylor Buchanan has pointed out, I can see that you have used 3 different controllers in your template. multiController , ImageCropperCtrl & insideController . I don't understand why those many controllers are needed.

Also you don't need separate ng-model at textarea.

Looking at your requirement I think a single controller is sufficient. Here is sample code @ plunker that shows how the image cropper can be used and how you can get the cropped image data in controller.

script.js

angular.module('myApp', ['angular-img-cropper']);

angular.module('myApp').controller("multiController",[ '$scope', function($scope)
{
    $scope.cropper = {};
    $scope.cropper.sourceImage = null;
    $scope.cropper.croppedImage   = null;
    $scope.bounds = {};
    $scope.bounds.left = 0;
    $scope.bounds.right = 0;
    $scope.bounds.top = 0;
    $scope.bounds.bottom = 0;

    $scope.clickButton = function () {
        console.log("photo: "+ $scope.cropper.croppedImage);
    };
}]);

index.html

<!DOCTYPE html>
<html>

  <head>
    <script data-require="jquery@2.2.4" data-semver="2.2.4" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
    <link rel="stylesheet" href="style.css" />
  </head>

  <body ng-app="myApp" ng-controller="multiController">
    <h1>Image Cropper Demo</h1>
    <div>
      <input img-cropper-fileread="" image="cropper.sourceImage" type="file" />
      <div>
        <canvas width="500" height="300" id="canvas" image-cropper="" image="cropper.sourceImage" cropped-image="cropper.croppedImage" crop-width="400" crop-height="200" keep-aspect="true" touch-radius="30" crop-area-bounds="bounds"></canvas>
      </div>
      <div>Cropped Image (Left: {{bounds.left}} Right: {{bounds.right}} Top: {{bounds.top}} Bottom: {{bounds.bottom}})</div>
      <div ng-show="cropper.croppedImage!=null">
        <img ng-src="{{cropper.croppedImage}}" />
      </div>
      <textarea name="member_photo" id="member_photo" class="form-control valid">{{cropper.croppedImage}}</textarea>
      <button ng-click="clickButton()">Console.log</button>
    </div>

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js"></script>
    <script src="angular-img-cropper.min.js"></script>
    <script src="script.js"></script>
  </body>

</html>

Note: As I have not used route provider, I had to explicitly specify ng-controller at body level. When you use route provider you don't need to specify ng-controller in your template. Check the example given at $route

You have to specify the callback function in your template and implement the crop callback function in your controller. For example :

In template:

crop-callback="myCallbackFunction"

In controller:

vm.myCallbackFunction = function(base64) {
  vm.resultImage = base64;
  $scope.$apply(); // Apply the changes.
};

You have a variety of issues, mostly stemming from copying and pasting the library example. If you are new to Angular, I strongly suggest reviewing the Angular documentation and examples prior to implementing any additional libraries. That being said, here are some of the issues:

  1. You are referencing a controller in the template that is not defined. ImageCropperCtrl is a controller defined in the example, but not in the code you provided.

     <div ng-controller="ImageCropperCtrl as ctrl"> 

    This can probably just be removed since you've created your own controller.

  2. You are referencing an object called cropper throughout the template that is not defined in your controller. You can see in the example where they declare the object in the ImageCropperCtrl controller prior to using it:

     $scope.cropper = {}; 

    Once this variable is declared in your controller, you will be able to access the cropped image with $scope.cropper.croppedImage .

  3. You are attempting to reference your controller throughout the template as multiCtrl . This will only work if you use the controller as syntax (similar to what is shown in the library example: ImageCropperCtrl as ctrl ).

     <div ng-controller="multiController"> 

    would become:

     <div ng-controller="multiController as multiCtrl"> 
  4. You are using both ng-model and interpolation ( {{}} ) for the textarea . You probably only want ng-model , but I'm not really sure what you're trying to do here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM