12641


JavaScriptベースのフロントエンドアプリケーションとして AnuglarJS を使用して  
サーバ側のデータを操作する為にバックエンドAPIを Rails で構築しているのですが、  
ng-file-uploadを採用した画像のアップロードが上手く出来なくて困っています。

Shop(1) <-> Item(n)

1件のShopに複数のItemが紐付いている状態で、Shopのedit画面で画像のアップロードを実装しています。  
itemリストのループの中でそれぞれのitemに画像を登録させたいですが、ループの中では適切にアップロードができません。  
(厳密にはcontrollerの $scope.upload = (files) -> が呼び出されません。。)

また、現状ではそれぞれのitemごとに画像を設定することができなくて詰まっています。。  
APIを通してDBには正しく格納できているのでページをリロードすればきちんと表示されるのですが、  
img ngf-src="files[0]" ngf-default-src="" ngf-accept="'image/*'"  
がすべてのinputに対して共通のために、関係のないitemのimgが上書きされていしまいます。

一度に複数の画像アップロードや画像以外のアップロードは求めていなく、  
いたってシンプルなものをつくろうとしているのですがなかなか上手くいきません...  
どうかご教授いただけますと嬉しいです。

application.js

[code]

    //= require angular.min
    //= require angular-resource.min
    //= require ng-file-upload.min
    //= require ng-file-upload-shim.min
    //= require app
    //= require_tree .
    
[/code]

controller.coffee

[code]

    angular.module('kapiyva').controller "ArticleEditController", ($scope, Upload, Shop, Item) ->
    
      $scope.init = ->
    
      $scope.$watch 'files', ->
        $scope.upload $scope.files
        return
    
      $scope.upload = (files) ->
        if files and files.length
          alert "success"
          i = 0
          while i < files.length
            file = files[i]
            $scope.upload = Upload.upload(
              url: '/api/shops/1/items'
              method: 'POST'
              # shop_idを動的に渡せていないので一時的にベタ書きしています
              fields: 'item[shop_id]':'1'
              file: file
              fileFormDataName: 'item[image]')
            i++
          return
    
[/code]

edit.html.slim

[code]

    # ループの外では適切にアップロードされる
    section
      p select file:
      input type="submit" value="ファイルを選択" ngf-select="" ng-model="files"
      img ngf-src="files[0]" ngf-default-src="" ngf-accept="'image/*'"
    section
      p select file:
      input type="submit" value="ファイルを選択" ngf-select="" ng-model="files"
      img ngf-src="files[0]" ngf-default-src="" ngf-accept="'image/*'"
    section
      p select file:
      input type="submit" value="ファイルを選択" ngf-select="" ng-model="files"
      img ngf-src="files[0]" ngf-default-src="" ngf-accept="'image/*'"
    
    # ループの中では $scope.upload = (files) -> が呼ばれない...
    ul ng-repeat="item in shop.items"
      p select file:
      input type="submit" value="ファイルを選択" ngf-select="" ng-model="files"
      img ngf-src="files[0]" ngf-default-src="" ngf-accept="'image/*'"
    
[/code]


CC BY-SA 3.0
2015-07-21T05:41:10.950
12519
2015-07-24T07:42:32.747
9900
question
angularjs coffeescript
ng-file-uploadを使用した画像のアップロードについて


`ngf-change`を使用して`$parent.upload`を呼んでみるのはどうでしょうか？

[code]

    .container
      ul
        li(ng-repeat='item in items')
          p {{item.name}}
          input(type="submit" value="ファイルを選択" ngf-select ngf-change="$parent.upload(item, $files)" ng-model="files")
          br
          img(ngf-src="files[0]" ngf-default-src="" ngf-accept="'image/*'")
    
[/code]

Controller（抜粋）

[code]

    # これは不要
    # $scope.$watch 'files', ->
    #     $scope.upload $scope.files
    #     return
    
    $scope.upload = (item, files) ->
    
      # ファイル未選択の場合は何もしない
      if !(files and files.length)
        return
    
      console.log 'id:' + item.id
      console.log files[0]
    
      Upload.upload({
          url: 'xxx/xxx',
          file: files[0]
      }).success((data, status, headers, config) ->
          console.log 'file ' + config.file.name + 'uploaded. Response: ' + data
      ).error((data, status, headers, config) ->
          console.log 'error status: ' + status
      )
    
[/code]


CC BY-SA 3.0
2015-07-24T07:42:32.747
12641
2015-07-24T07:42:32.747
3516
12519
answer