#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
andImageCropperCtrl
. В этомmultiController
был мой иImageCropperCtrl
был обрезчик. Я думалImageCropperCtrl
, что это требуется для обрезки. Тем не менее, я этого не понимаю. Обрезка будет доступна только путем введения модуля? Иcropper
доступна ли она внутриmultiController
?2. Мы определяем
cropper
объект внутри нашего контроллера и используем его в html. Вы можете назвать ее как угодно, но вам нужно будет использовать ту же переменную в вашем html. И для функциональности обрезкиangular-img-cropper
определено несколькоdirectives
(напримерimg-cropper-fileread
,image-cropper
,image
,cropped-image
, ……) это делает волшебство обрезки изображения и сохранения его в вашей переменной, которую вы присваиваетеcropped-image
. HTH3. Код работает без объекта обрезки, объявленного в контроллере.
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 перед внедрением каких-либо дополнительных библиотек. При этом, вот некоторые из проблем:
-
Вы ссылаетесь на контроллер в шаблоне, который не определен.
ImageCropperCtrl
контроллер определен в примере, но не в предоставленном вами коде.<div ng-controller="ImageCropperCtrl as ctrl">
Вероятно, это можно просто удалить, поскольку вы создали свой собственный контроллер.
-
Вы ссылаетесь на объект, вызываемый
cropper
по всему шаблону, который не определен в вашем контроллере.Вы можете видеть в примере, где они объявляют объект вImageCropperCtrl
контроллере перед его использованием:$scope.cropper = {};
Как только эта переменная будет объявлена в вашем контроллере, вы сможете получить доступ к обрезанному изображению с
$scope.cropper.croppedImage
помощью . -
Вы пытаетесь ссылаться на свой контроллер по всему шаблону как
multiCtrl
.Это будет работать, только если вы используете контроллер в качестве синтаксиса (аналогично тому, что показано в примере библиотеки:ImageCropperCtrl as ctrl
).<div ng-controller="multiController">
станет:
<div ng-controller="multiController as multiCtrl">
-
Вы используете оба
ng-model
и интерполяцию ({{}}
) дляtextarea
.Вы, вероятно, только хотитеng-model
, но я не совсем уверен, что вы пытаетесь здесь сделать.
Комментарии:
1. Все проблемы, на которые я указал, действительны. Если вы собираетесь понизить голос, оставьте фактическую причину.