Не удается получить доступ к переменной внутри контроллера в angular

#javascript #angularjs

#javascript #angularjs

Вопрос:

Я пытаюсь реализовать библиотеку плагинов для обрезки в моем демонстрационном проекте angular. Я ввел необходимые модули в свой основной модуль и успешно обрезал изображение. Но я не знаю, как передать строку base64 контроллеру. То, что я пробовал до сих пор, это:

 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>
  

Если я проверяю текстовую область, значение есть, но оно не отображается внутри текстовой области, а также значение не может быть доступно внутри моего контроллера. Что я делаю не так?

Комментарии:

1. Вы используете контроллер в качестве синтаксиса, не указывая псевдоним для контроллера в HTML. Вам нужно использовать ng-model=»vm.member_photo». то же самое для вашего ng-click. Кроме того, у вас обоих есть ng-model, и {{}} with эквивалентно ng-bind. Вам нужно использовать только одну

Ответ №1:

Как уже указывал @Taylor Buchanan, в вашем коде есть несколько проблем. И я также рекомендую вам ознакомиться с документацией и примерами Angular.

Помимо проблем, на которые указал @Taylor Buchanan, я вижу, что вы использовали 3 разных контроллера в своем шаблоне. multiController , ImageCropperCtrl amp; insideController . Я не понимаю, зачем нужно столько контроллеров.

Также вам не нужна отдельная ng-модель в текстовой области.

Глядя на ваше требование, я думаю, что одного контроллера достаточно. Вот пример кода @ plunker, который показывает, как можно использовать средство обрезки изображений и как вы можете получить обрезанные данные изображения в контроллере.

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>
  

Примечание: поскольку я не использовал поставщика маршрутов, мне пришлось явно указать ng-controller на уровне тела. Когда вы используете поставщика маршрутов, вам не нужно указывать ng-controller в своем шаблоне. Проверьте пример, приведенный в $route

Комментарии:

1. Спасибо за помощь. Я новичок в Angular. И это insideController была ошибка в коде. На самом деле я использовал multiController and ImageCropperCtrl . В этом multiController был мой и ImageCropperCtrl был обрезчик. Я думал ImageCropperCtrl , что это требуется для обрезки. Тем не менее, я этого не понимаю. Обрезка будет доступна только путем введения модуля? И cropper доступна ли она внутри multiController ?

2. Мы определяем cropper объект внутри нашего контроллера и используем его в html. Вы можете назвать ее как угодно, но вам нужно будет использовать ту же переменную в вашем html. И для функциональности обрезки angular-img-cropper определено несколько directives (например img-cropper-fileread , image-cropper , image , cropped-image , ……) это делает волшебство обрезки изображения и сохранения его в вашей переменной, которую вы присваиваете cropped-image . HTH

3. Код работает без объекта обрезки, объявленного в контроллере.

4. Ссылка: docs.angularjs.org/api/ng/directive/ngModel Примечание: ngModel попытается выполнить привязку к заданному свойству путем вычисления выражения в текущей области. Если свойство еще не существует в этой области, оно будет создано неявно и добавлено в область.

5. Я 🙂 , только что сказал.

Ответ №2:

Вы должны указать функцию обратного вызова в своем шаблоне и реализовать функцию обратного вызова crop в вашем контроллере. Например :

В шаблоне:

 crop-callback="myCallbackFunction"
  

В контроллере:

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

Комментарии:

1. Я вроде как новичок в angular. Не могли бы вы сказать мне, куда поместить обратный вызов?

2. Хорошо, тогда вам нужно указать, какую именно библиотеку вы используете для функции обрезки.. есть ли ссылка на этот документ библиотеки?

3. Это упоминается в вопросе. В самом первом предложении. Вот оно: github.com/AllanBishop/angular-img-cropper

Ответ №3:

У вас есть множество проблем, в основном связанных с копированием и вставкой примера библиотеки. Если вы новичок в Angular, я настоятельно рекомендую ознакомиться с документацией и примерами Angular перед внедрением каких-либо дополнительных библиотек. При этом, вот некоторые из проблем:

  1. Вы ссылаетесь на контроллер в шаблоне, который не определен. ImageCropperCtrl контроллер определен в примере, но не в предоставленном вами коде.

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

    Вероятно, это можно просто удалить, поскольку вы создали свой собственный контроллер.

  2. Вы ссылаетесь на объект, вызываемый cropper по всему шаблону, который не определен в вашем контроллере.Вы можете видеть в примере, где они объявляют объект в ImageCropperCtrl контроллере перед его использованием:

     $scope.cropper = {};
      

    Как только эта переменная будет объявлена в вашем контроллере, вы сможете получить доступ к обрезанному изображению с $scope.cropper.croppedImage помощью .

  3. Вы пытаетесь ссылаться на свой контроллер по всему шаблону как multiCtrl .Это будет работать, только если вы используете контроллер в качестве синтаксиса (аналогично тому, что показано в примере библиотеки: ImageCropperCtrl as ctrl ).

     <div ng-controller="multiController">
      

    станет:

     <div ng-controller="multiController as multiCtrl">
      
  4. Вы используете оба ng-model и интерполяцию ( {{}} ) для textarea .Вы, вероятно, только хотите ng-model , но я не совсем уверен, что вы пытаетесь здесь сделать.

Комментарии:

1. Все проблемы, на которые я указал, действительны. Если вы собираетесь понизить голос, оставьте фактическую причину.