Search code examples
javascriptangularjsmodel-view-controllerdynamicform

AngularJS controller returns form


developers!

I decided to try Angular, so I want to make simple image uploading and editing app, in MVC (or close to it) architecture.

And I stuck on entrance point, because of I don't really know how to properly return filled main form from template.

As I think for now - I call controller function first, then it should call mainService function, which builds form, which uses 'imageUploadController' which using imageUploadService.

But I somesthing tells me that it's not okay to do things like that.

My main problem is how to get uploadImageForm.html, pass it to index.html, whithout links or includes (I just want to keep things separately) make sure that services and controllerrs there working properly

How the best practices looks like in same situation?

Here's the code, hope it helps to see problem I got more clearly:

Here's my index.html

<!doctype html>
<html lang="en" ng-app="modernFilter">
  <head>
    <meta charset="utf-8">
    <title>Modern.Filters</title>
    <script src="asstes/libs/angular.min.js"></script>
    <script src="app/components/app.js"></script>
    <script src="app/shared/imageUploadController.js"></script>
  </head>
  <body ng-controller = "mainController">
    <span>{{mainForm}}</span>
  </body>
</html>

Here is app.js

'use strict';

// Define the `modern.filter` module
var modernFilterApp = angular.module('modernFilter', []);

//  Define main controller

modernFilterApp.controller('mainController', ['$scope', function($scope, mainService){
    // Stores form data
    $scope.mainForm = null;

    // Returns main form template
    $scope.getMainForm = function(){
        $scope.mainForm = mainService.getMainForm();
    }

    // Call function on documentready
    angular.element(document).ready(function () {
        $scope.getMainForm();

        //todo: is it even okay? but without it nothing happens
        $scope.$apply();
    })

}]);

// Define service

modernFilterApp.service('mainService', function(mainService){
    this.getMainForm = function(){
        // todo: how should I get template here?
        return "filled form template from here"
    }
});

Also I got template imageUploadView

<div ng-controller="imageUploadController">
<canvas id="imageCanvas"></canvas>
<form action="">
    <input my-upload type="file" name="upload" onchange="angular.element(this).scope().uploadImage()">
</form>

Cotroller and service for it (with example code, still debugging it)

modernFilterApp.controller('imageUploadController', ['$scope', 'imageUploadService', function($scope, imageUploadService) {
  // Stores image
  $scope.image = null;

  // Returns main form template
  $scope.uploadImage = function() {
    $scope.image = imageUploadService.handleImage(arguments);
  }

}]);

//  Define upload service

modernFilterApp.service('imageUploadService', function(imageUploadService) {

// Function handles uploaded files (dirty code)
this.handleImage = function(event) {
  var canvas = angular.element('#imageCanvas'),
    context = canvas.getContext('2d'),
    reader = new FileReader(),
    img = new Image();

  canvas.width = img.width;

  canvas.height = img.height;
  context.drawImage(img, 0, 0);
  img.src = event.target.result;
  return reader.readAsDataURL(e.target.files[0]);
}

}]);

Solution

  • Dont try to get the template from the controller.

    You need to use directive. Make directive with its controller as imageUploadController , its template as imageUploadView and include it inside the index.html

    Your html :-

    <body ... >
      <my-directive></my-directive>
    </body>
    //include directive file,controller files
    

    Directive :-

        .directive('myDirective', ['your service',function(your service) {
      return {
        restrict: 'E',
        transclude: true,
        scope: {},
        templateUrl: 'template url',
        link: function (scope) {
    
        },
        controller : function($scope){
        //your controller
        }
      };
    }]);
    

    Refer here

    Html will be automatically rendered in place of directive