質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.61%

  • AngularJS

    565questions

    AngularJSはオープンソースのJavaScriptフレームワークです。ブラウザ上で動作するウェブアプリケーションの開発にMVCアーキテクチャを取り入れることを目的としています。

  • CoffeeScript

    137questions

    CoffeeScriptはプログラミング言語です。シンタックスシュガーの導入により、JavaScriptのコードに変換された後動作します。JavaScriptに比べ、可読性と簡潔性が向上しています。

  • Slim

    74questions

    SlimはPHPアプリケーションを開発するための軽量なマイクロフレームワークです。

ng-file-uploadを使用した画像のアップロードがループの中で動作せず困っています

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,824
退会済みユーザー

退会済みユーザー

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
//= require angular.min
//= require angular-resource.min
//= require ng-file-upload.min
//= require ng-file-upload-shim.min
//= require app
//= require_tree .

controller.coffee
angular.module('app').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

edit.html.slim
# ループの外では適切にアップロードされる
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/*'"
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

似たような事例がstacoverflowで回答されています。こちらで解決できないでしょうか?
http://stackoverflow.com/questions/31313845/angularjs-ng-file-upload-not-working-inside-ng-repeat

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/07/22 13:32

    回答ありがとうございます。こちらの事例で回答されているものでは解決できませんでした...

    キャンセル

  • 2015/07/22 14:02

    ng-model="files"

    ng-model="item.files"
    にするだけでなく、
    $scope.$watch 'item.files', ->
    を追加されていますか?
    またitem.filesはng-repeatされる前に定義済みの状態でしょうか?

    キャンセル

  • 2015/07/22 17:44

    ご回答ありがとうございます。"item.filesがng-repeatされる前に定義済みの状態" というのがいまいち分かりませんがご回答いただいた点を受けて以下のようにしています。しかしながら Cannot read property 'files' of undefinedとなり $scope.upload = (item) -> が呼ばれない状態です(画像のプレビューまでは問題なく行えています)。


    [edit.html.slim]
    section ng-repeat="item in shop.items"
    p select file:
    input type="submit" value="ファイルを選択" ngf-select="" ng-model="item.files"
    img ngf-src="item.files[0]" ngf-default-src="" ngf-accept="'image/*'"


    [controller.coffee]
    $scope.$watch 'item.files', ->
    $scope.upload $scope.item.files
    return

    $scope.upload = (item) ->
    if item.files and item.files.length
    alert "upload start"
    file = item.files[0]
    $scope.upload = Upload.upload(
    url: '/api/shops/1/items'
    method: 'POST'
    # shop_idを動的に渡せていないので一時的にベタ書きしています
    fields: 'item[shop_id]':'1'
    file: file
    fileFormDataName: 'item[image]')
    return

    キャンセル

  • 2015/07/23 13:25 編集

    少し修正しました。エラーは吐かなくなりましたが、やはり $scope.upload = (files) -> が呼ばれない状態が直りません(ngf-src="item.files[0]"には適切に値が返され、画像は表示されるのですがDBには格納されない状態です)。おかしな点があればどうか指摘していただきたいです。よろしくお願いいたします。

    [edit.html.slim]
    section ng-repeat="item in shop.items"
    p select file:
    input type="submit" value="ファイルを選択" ngf-select="" ng-model="item.files"
    img ngf-src="item.files[0]" ngf-default-src="" ngf-accept="'image/*'"


    [controller.coffee]
    # $scope.item.files = []
    $scope.$watch 'item.files', ->
    $scope.upload $scope.files
    return

    $scope.upload = (files) ->
    if files and files.length
    alert "upload start"
    file = item.files[0]
    $scope.upload = Upload.upload(
    url: '/api/shops/1/items'
    method: 'POST'
    # shop_idを動的に渡せていないので一時的にベタ書きしています
    fields: 'item[shop_id]':'1'
    file: file
    fileFormDataName: 'item[image]')
    return

    キャンセル

  • 2015/07/23 15:06

    onchangeでもファイルの変更は検知できると思いますので、そちらでやってみたらいかがですか?
    http://stackoverflow.com/questions/23983580/pass-angularjs-index-into-onchange

    キャンセル

  • 2015/07/24 13:25

    コメントありがとうございます。onchangeも検討しましたが将来的にはドラッグ&ドロップでのアップロードに対応させたいと考えているのでできればmodelでファイルの変更を監視したいです。

    キャンセル

  • 2015/07/24 14:03

    > 似たような事例がstacoverflowで回答されています。こちらで解決できないでしょうか?
    初期の回答を試してみましたが、ng-repeat内でもモデルの変更は取れました。
    すみませんが、$scope.$watch 'item.files', ->ではいかないようなので、stacoverflowに書かれているようなコードで試してみてはいかがでしょうか?

    キャンセル

  • 2015/07/24 16:28

    コメントありがとうございます。どこかで間違ったことをしているはずなのでもう少し試行錯誤してみます。。ありがとうございます!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • AngularJS

    565questions

    AngularJSはオープンソースのJavaScriptフレームワークです。ブラウザ上で動作するウェブアプリケーションの開発にMVCアーキテクチャを取り入れることを目的としています。

  • CoffeeScript

    137questions

    CoffeeScriptはプログラミング言語です。シンタックスシュガーの導入により、JavaScriptのコードに変換された後動作します。JavaScriptに比べ、可読性と簡潔性が向上しています。

  • Slim

    74questions

    SlimはPHPアプリケーションを開発するための軽量なマイクロフレームワークです。