2014-12-21 6 views
0

У меня есть backback-интерфейс API с хранилищем, который хранит изображения и формирует данные, которые я отправляю. Тестирование API само по себе работает, поэтому очевидно, что в моей логике в моем контроллере что-то отсутствует. Я использую angular-file-upload & код https://github.com/strongloop/loopback-component-storage/tree/master/example-2.0Угловая & Loopback multiform POST не работает, почему?

Так что я в основном пытаюсь опубликовать форму, которая сначала бросает изображение в контейнер на сервере API, а затем, когда я нажимаю кнопку submit, я пытаюсь вытащить имя изображения из объекта, созданного пользователем, и отправить его по другим входам формы.

Когда я отправляю с помощью формы, на консоли я получаю ошибку Network 422 в свойстве Image - не может быть пустым. БД берет строку для этого свойства.

Контроллер

app.controller('exampleCtrl', function($scope, $http, $resource, clientsUrl, $fileUploader, $window) { 

//Code for uploading files to API - NEED TO WORK ON IT 
'use strict'; 

// create a uploader with options 
var uploader = $scope.uploader = $fileUploader.create({ 
    scope: $scope,       // to automatically update the html. Default: $rootScope 
    url: 'http://www.example.com:3000/api/containers/container1/upload', 
    formData: [ 
    { key: 'value' } 
    ], 
    filters: [ 
    function (item) {     // first user filter 
     console.info('filter1'); 
     return true; 
    } 
    ] 
}); 

// ADDING FILTERS 

uploader.filters.push(function (item) { // second user filter 
    console.info('filter2'); 
    return true; 
}); 

// REGISTER HANDLERS 

uploader.bind('afteraddingfile', function (event, item) { 
    console.info('After adding a file', item); 
}); 

uploader.bind('whenaddingfilefailed', function (event, item) { 
    console.info('When adding a file failed', item); 
}); 

uploader.bind('afteraddingall', function (event, items) { 
    console.info('After adding all files', items); 
}); 

uploader.bind('beforeupload', function (event, item) { 
    console.info('Before upload', item); 
}); 

uploader.bind('progress', function (event, item, progress) { 
    console.info('Progress: ' + progress, item); 
}); 

uploader.bind('success', function (event, xhr, item, response) { 
    console.info('Success', xhr, item, response); 
    $scope.$broadcast('uploadCompleted', item); 
}); 

uploader.bind('cancel', function (event, xhr, item) { 
    console.info('Cancel', xhr, item); 
}); 

uploader.bind('error', function (event, xhr, item, response) { 
    console.info('Error', xhr, item, response); 
}); 

uploader.bind('complete', function (event, xhr, item, response) { 
    console.info('Complete', xhr, item, response); 
}); 

uploader.bind('progressall', function (event, progress) { 
    console.info('Total progress: ' + progress); 
}); 

uploader.bind('completeall', function (event, items) { 
    console.info('Complete all', items); 
}); 


$scope.load = function() { 
    $http.get('http://www.example.com:3000/api/containers/container1/files').success(function (data) { 
    console.log(data); 
    $scope.files = data; 
    }); 
}; 

$scope.delete = function (index, id) { 
    $http.delete('http://www.example.com:3000/api/containers/container1/files/' + encodeURIComponent(id)).success(function (data, status, headers) { 
    $scope.files.splice(index, 1); 
    }); 
}; 

$scope.$on('uploadCompleted', function(event) { 
    console.log('uploadCompleted event received'); 
    $scope.load(); 
}); 


    $scope.clientsItemsResource = $resource(clientsUrl + ":id", {id: "@id"}, 
      { create : { method: "POST"}, save: { method: "PUT"}} 
     ); 

//Creates prototype for setting image on scope 
function SetImageScope($scope, $window){ 
    $scope.image = 'Superhero'; 

    SetImageScope.prototype.$scope = $scope; 
}; 

    //Sets the newClientsItem 
    SetImageScope.prototype.setFile = function(element) { 
     var $scope = this.$scope; 
     $scope.$apply(function(){ 
      $scope.newClientsItem = element.files[0]; 
     }); 
    }; 

    $scope.createClientsItem = function (clientsItem) { 

     //creates the new item 
    new $scope.clientsItemsResource(clientsItem).$create().then(function (newClientsItem) { 
    $scope.clientsItems.push(newClientsItem); 
    }); 
}; 
}); 

HTML

<div ng-controller="exampleCtrl" ng-file-drop="ng-file-drop" class="container"> 
<div class="row-fluid"> 
<div class="col-md-12"><br/></div> 
<form> 
    <div class="form-group"> 
    <label>Title</label> 
    <input type="text" ng-model="newClientsItem.title" required="required" class="form-control"/><br/> 
    <label>Link</label> 
    <input type="url" ng-model="newClientsItem.link" required="required" class="form-control"/><br/> 
    <label>Image</label> 
    <input ng-file-select="ng-file-select" type="file" onchange="SetImageScope.prototype.setFile(this)" class="btn btn-primary"/> 
    <table class="table"> 
     <thead> 
     <tr> 
      <th width="50%">Image</th> 
      <th ng-show="uploader.isHTML5">Size</th> 
      <th ng-show="uploader.isHTML5">Progress</th> 
      <th>Status</th> 
      <th>Actions</th> 
     </tr> 
     </thead> 
     <tbody> 
     <tr ng-repeat="item in uploader.queue"> 
      <td><strong>{{ item.file.name }}</strong></td> 
      <td ng-show="uploader.isHTML5" nowrap=""> 
      {{ 
      item.file.size/1024/1024|number:2 }} MB 
      </td> 
      <td ng-show="uploader.isHTML5"> 
      <div style="margin-bottom: 0;" class="progress"> 
       <div role="progressbar" ng-style="{ &quot;width&quot;: item.progress + &quot;%&quot; }" class="progress-bar"></div> 
      </div> 
      </td> 
      <td class="text-center"><span ng-show="item.isSuccess"><i class="glyphicon glyphicon-ok"></i></span><span ng-show="item.isCancel"><i class="glyphicon glyphicon-ban-circle"></i></span><span ng-show="item.isError"><i class="glyphicon glyphicon-remove"></i></span></td> 
      <td nowrap=""> 
      <button type="button" ng-click="item.upload()" ng-disabled="item.isReady || item.isUploading || item.isSuccess" class="btn btn-success btn-xs"><span class="glyphicon glyphicon-upload"></span>Upload</button> 
      <button type="button" ng-click="item.cancel()" ng-disabled="!item.isUploading" class="btn btn-warning btn-xs"><span class="glyphicon glyphicon-ban-circle"></span>Cancel</button> 
      <button type="button" ng-click="item.remove()" class="btn btn-danger btn-xs"><span class="glyphicon glyphicon-trash"></span>Remove</button> 
      </td> 
     </tr> 
     </tbody> 
    </table><a ng-click="createClientsItem(newClientsItem)" class="btn btn-default btn-lg">Ajouter</a> 
    </div> 
</form> 

+0

Когда я ваша проблема эта статья помогла мне: http://uncorkedstudios.com/blog/multipartformdata-file-upload-with-angularjs – simeg

+0

спасибо за подсказку и я на самом деле в этой статье время Я строю все это ... но чего-то не хватает в моей логике, которую я не вижу после работы над этим кодом некоторое время. Вы видите что-то, что я не вижу? –

+0

Возможно, недостаток 'headers' и' transformRequest'. Трудно сказать, так как я думаю, что вы используете совсем другой подход, чем в статье. Вы уверены, что DB берет простую строку, а не файл (содержащий некоторые другие вещи)? – simeg

ответ

0

422 код состояния означает, что проверка модели не был принят. Попытайтесь проверить отправленные данные на стороне клиента и сервера. Отладка с model hooks и Loopback debug strings должна помочь.

+0

Спасибо, и я знаю, что это отправленные данные. Посмотрите на код от SetImageScope до конца, я знаю, что он есть, но просто не вижу его, так как я работал над этим на некоторое время. API loopback и DB берут свойство {image: STRING} ... вы можете найти мою ошибку? –

+0

Я просмотрел ваш код и не видел вызова для 'SetImageScope', где вы сохраняете' $ scope' для прототипа и присоединяете свойство «image» к области видимости. В этом случае 'SetImageScope.prototype.setFile' видит' $ scope'? (Также ваш код немного сложнее, и в следующий раз для выполнения некоторых методов объема вы можете использовать 'onchange =" angular.element (this) .scope(). SetFile() "', чтобы вызвать функцию $ scope.sentFile , вместо того, чтобы работать с прототипами.) – IvanZh

0

Не уверен, что мое решение верное. Но вы можете рассмотреть их:

  1. Если вы хотите, чтобы сделать файл или отправить их в отдельном виде препровождающий, пусть взять попробовать на перемещение файла <input> тега из <form> тега.

  2. В вашем коде не установлены координаты 'multipart' для загрузки. Это может вызвать проблему.