Angular.js: 입력[유형=파일] 바인딩 지원

에 만든 2012년 09월 18일  ·  145코멘트  ·  출처: angular/angular.js

안녕하세요 간단한 파일 업로드를 시도하고 있습니다.

forms moderate not core feature

가장 유용한 댓글

이 솔루션은 구현되는 파일 판독기에 따라 다릅니다.

...
.directive('file', function() {
    return {
        restrict: 'E',
        template: '<input type="file" />',
        replace: true,
        require: 'ngModel',
        link: function(scope, element, attr, ctrl) {
            var listener = function() {
                scope.$apply(function() {
                    attr.multiple ? ctrl.$setViewValue(element[0].files) : ctrl.$setViewValue(element[0].files[0]);
                });
            }
            element.bind('change', listener);
        }
    }
});

<file name="image" ng-model="inputFile" accept="image/png,image/jpg,image/jpeg" />

그런 다음 몇 가지 xhr 작업을 직접 수행해야 하지만 이것이 GUI 바인딩 및 더 많은 처리 논리 외부에 있다고 생각합니다.

그리고 상상력이 부족하다면:

var file = $scope.inputFile;
$http.put('http://localhost:5984/demo/d06917e8d1fae1ae162ea7773c003f0b/' + file.name + '?rev=4-c10029f35a5c5ed9bd8cc31bf8589d3c', file, { headers: { 'Content-Type' : file.type } });

이것은 xhr2(http://www.html5rocks.com/en/tutorials/file/xhr2)로 인해 작동하며 긴 예제 업로드 URL, 해당 카우치DB 문서 끝점(첨부 파일)을 양해해 주십시오.

모든 145 댓글

입력 type=file에 대해 angular에서 제공하는 기본 바인딩이 없습니다.

그러나 파일 입력은 자바 스크립트에만 적용되며 이러한 바인딩이 도움이 될 수 있는 유일한 이점은 파일 입력을 지우는 것입니다. (Angular는 현재 파일의 ajax 업로드에 대한 프레임워크 지원도 제공하지 않습니다.)

@coli :

input[file]에서 onchange 이벤트를 포착할 수 있다는 것은 의미가 있습니다.

https://github.com/lgersman/jquery.orangevolt-ampere 에는 XMLHTTPRequest V2를 통한 파일 업로드라는 시나리오가 있습니다.
따라서 페이지를 다시 로드하지 않고 파일 업로드를 완료하기 위해 input[file] 변경 이벤트를 포착하는 자체 지시문을 구현했습니다.

angularjs에서 그 기능을 보고 싶습니다!

파일 유형의 입력에 바인딩하는 데 진전이 있었습니까? 나는 해결책을 찾고 있었고 작동하는 것을 찾을 수없는 것 같습니다 ...

내 솔루션은 요청 또는 http.post 대신 Ajax였습니다.

내 iPad에서 보낸

2013년 3월 1일 오후 7시 16분에 "jgoldber" < [email protected] [email protected] >이(가) 다음과 같이 썼습니다.

파일 유형의 입력에 바인딩하는 데 진전이 있었습니까? 나는 해결책을 찾고 있었고 해결책을 찾지 못한 것 같습니다.


이 이메일에 직접 답장하거나 Gi tHubhttps://github.com/angular/angular.js/issues/1375#issuecomment -14321221에서 확인하세요.

내가 찾은 최고의 솔루션 : http://jsfiddle.net/marcenuc/ADukg/49/. 더 나은 솔루션을 찾으면 공유하십시오.

예, 이것은 정말 살펴봐야 합니다. 파일을 선택하고 업로드할 수 있는 것은 대부분의 웹 애플리케이션에서 상당히 중요하므로 이 입력을 지원하는 것은 분명히 누락된 기능입니다.

충돌. 이것은 이정표에 추가해야 합니다.

이를 지지하는 또 다른 외침.

ng-model 파일은 HTML5 File API의 파일에 값을 설정할 수 있습니다. IE8/IE9용 Flash 및 Silverlight 폴리필이 있습니다.

예, 값을 파일로 설정하거나 입력 요소(파일에 대한 참조 포함)로 설정합니다.

이 솔루션은 구현되는 파일 판독기에 따라 다릅니다.

...
.directive('file', function() {
    return {
        restrict: 'E',
        template: '<input type="file" />',
        replace: true,
        require: 'ngModel',
        link: function(scope, element, attr, ctrl) {
            var listener = function() {
                scope.$apply(function() {
                    attr.multiple ? ctrl.$setViewValue(element[0].files) : ctrl.$setViewValue(element[0].files[0]);
                });
            }
            element.bind('change', listener);
        }
    }
});

<file name="image" ng-model="inputFile" accept="image/png,image/jpg,image/jpeg" />

그런 다음 몇 가지 xhr 작업을 직접 수행해야 하지만 이것이 GUI 바인딩 및 더 많은 처리 논리 외부에 있다고 생각합니다.

그리고 상상력이 부족하다면:

var file = $scope.inputFile;
$http.put('http://localhost:5984/demo/d06917e8d1fae1ae162ea7773c003f0b/' + file.name + '?rev=4-c10029f35a5c5ed9bd8cc31bf8589d3c', file, { headers: { 'Content-Type' : file.type } });

이것은 xhr2(http://www.html5rocks.com/en/tutorials/file/xhr2)로 인해 작동하며 긴 예제 업로드 URL, 해당 카우치DB 문서 끝점(첨부 파일)을 양해해 주십시오.

이 플래시 기반 FileReader Polyfill https://github.com/Jahdrien/FileReader 와 FileReader https://github.com/francois2metz/에 의존하는 순수 js FormData 폴리필을 결합하여 IE8/9에서 이 작업을 수행할 수 Moxie 는 더 나은 폴리필입니다.

내 솔루션은 적어도 컨트롤러 프로토타입이 만지작거리는 위의 jsfiddle만큼 스케치가 거의 없었습니다.

컨트롤러에서:

    $scope.updateImage = '(' + function () {
      alert('moo');
    }.toString() + ')();';

원하는 onchange 콜백을 문자열화하고 클로저로 래핑합니다.

   <input type="file" name="image" onchange="{{updateImage}}" ng-model="image">

Angular를 사용하여 DOM에 삽입

정확하지는 않지만 Webkit에서 작동합니다. 크로스 브라우저 테스트는 하지 않았습니다.

나는 1.0.5에 있고 그것은 여전히 ​​깨졌습니다. Jgoldber의 예를 사용하고 약간 수정했습니다.
http://jsfiddle.net/ADukg/2589/

이 예제는 하나의 컨트롤러에서만 작동하므로 여러 컨트롤러가 있고 각각 파일 입력이 있는 경우 약간의 변경이 필요합니다.

아직 IE에서 테스트하지 않았지만 제 추측(IE를 알고 있음)은 작동하지 않을 것입니다.

입력 요소를 인수로 사용하는 범위에서 함수를 호출하려고 한다고 가정하면 지시문에서 구현하는 것이 매우 간단합니다.

http://jsfiddle.net/neilsarkar/vQzKJ/

(위의 jsfiddle에서 수정됨, @programmist에게 감사드립니다)

'use strict';

function filesModelDirective(){
  return {
    controller: function($parse, $element, $attrs, $scope){
      var exp = $parse($attrs.filesModel);

      $element.on('change', function(){
        exp.assign($scope, this.files);
        $scope.$apply();
      });
    }
  };
}

구성:

angular.module(...).directive('filesModel', filesModelDirective)

용법:

<input type="file" files-model="someObject.files" multiple>

이 문제를 빨리 해결하십시오.

여전히 문제가 있습니다. 일부 버전에서는 작동하지만 어쨌든 지원되지 않습니다.

1.5.0 이후로 onchange 해결 ​​방법을 사용하는 경우 $digest를 호출해야 합니다.

<input type="file" onchange="angular.element(this).scope().myController.uploadFile(this.files[0]); angular.element(this).scope().$digest();">

ng-change 및 입력/파일에 대한 더 나은 지원을 위해 +1. 사용 사례: 이미지 업로더로서 최적의 표시를 위해 업로드하기 전에 해당 이미지를 편집(크기 조정 및 자르기)할 수 있기를 바랍니다. 구현: 입력/파일을 사용하여 이미지를 찾아보고 onchange 이벤트에서 파일을 캔버스로 이동하고 fabricjs로 편집합니다. 비 변경 구현을 생각할 수 없습니다.

cztomsik - 저는 1.0.7을 사용 중이며 솔루션이 작동하도록 할 수 없습니다. - scope(this) 함수는 잘 해결되지만 컨트롤러를 찾을 수 없습니다. uploadFile 함수는 scope(this)의 구성원으로 나열됩니다.

장난, 나는 나를 위해 작동하는 것으로 보이는 기술에 약간의 수정이 있습니다 (나는 여전히 내가 왜 가지고 있는지 모르겠습니다 :

< 입력 유형="파일" 이름="파일" ng-model="파일" onchange="invokeUploadFile(this)"/ >

var invokeUploadFile = 함수(그) {
angular.element(that).scope().uploadFile(that)
angular.element(that).scope().$digest();
}

jsfiddle/plunker를 제공할 수 있습니까?
고마워


    1. 2013년 v 18:17, tb01923 알림 @github.com :

ng-change 및 입력/파일에 대한 더 나은 지원을 위해 +1. 사용 사례: 이미지 업로더로서 최적의 표시를 위해 업로드하기 전에 해당 이미지를 편집(크기 조정 및 자르기)할 수 있기를 바랍니다. 구현: 입력/파일을 사용하여 이미지를 찾아보고 onchange 이벤트에서 파일을 캔버스로 이동하고 fabricjs로 편집합니다. 비 변경 구현을 생각할 수 없습니다.

cztomsik - 1.0.7을 사용 중이고 솔루션이 작동하도록 할 수 없습니다. - scope(this) 함수는 잘 해결되지만 컨트롤러를 찾을 수 없습니다. uploadFile 함수는 scope(this) 개체의 멤버로 나열되지만 내가 내가 얻는 컨트롤러를 제거하십시오

잡히지 않은 참조 오류: uploadFile이 정의되지 않았습니다. blah.js:15
$scope.uploadFile blah.js:15
invokeScope blah.js:4
온체인지


이 이메일에 직접 답장하거나 GitHub에서 확인하세요.

+1. 사용자가 파일을 선택할 때 HTML5 파일 업로드를 시작하는 데 필요합니다. 해결하기 쉽지만 이것이 효과가 있기를 기대합니다.

+1. 구현하지 말고 구현하십시오. 완전히 직관적이지 않습니다.

+1

+1

얘들아.. 1년이 넘었고 Angular 1.2.0에는 입력 파일 바인딩이 없습니다... 기능이 추가되지 않는 이유를 모르겠습니다. 구현에 대한 몇 가지 좋은 솔루션이 있습니다. 이 문제에 대해 Angular 팀 구성원의 답변을 원합니다.

최고의 솔루션 중 하나를 인용하기 위해 (단방향 데이터 바인딩이라는 것을 알고 있지만 여전히 없는 것보다 낫습니다. 유효성 검사 및 모델 업데이트는 IE7에서도 작동합니다):

정의

  /**
   * <strong i="8">@ngdoc</strong> inputType
   * <strong i="9">@name</strong> angular.module.ng.$compileProvider.directive.input.file
   *
   * <strong i="10">@description</strong>
   * HTML file input field.
   *
   * <strong i="11">@param</strong> {string} ngModel Assignable angular expression to data-bind to.
   * <strong i="12">@param</strong> {string} multiple Allows multiple files selection.
   * <strong i="13">@param</strong> {string=} name Property name of the form under which the 
                                control is published.
   *
   * <strong i="14">@example</strong>
      <doc:example>
        <doc:source>
         <script>
           function Ctrl($scope) {
           }
         </script>
         <form name="myForm" ng-controller="Ctrl">
           file: <input type="file" ng-model="file"> single file selection.<br/>
           files: <input type="file" ng-model="files" multiple> multi-file selection.<br/>
           <tt>file.name = {{file.name}}</tt><br/>
           <tt>files.length = {{files.length}}</tt><br/>
          </form>
        </doc:source>
        <doc:scenario>
          it('should change state', function() {
            expect(binding('file.name')).toBeUndefined();

            input('file').select('a file name');
            expect(binding('file.name')).toEqual('a file name');
          });
        </doc:scenario>
      </doc:example>
   */
  'file': fileInputType,

기능

function fileInputType(scope, element, attr, ctrl) {
  element.bind('change', function() {
    scope.$apply(function() {
      var files = element[0].files,
          isValid = true;

      if (msie < 10) {
        files = [element[0].value];
      }

      if (attr.accept) {
        var i, j, acceptType, fileType,
            types = map(attr.accept.split(','), function(t) { return trim(t).split('/'); });
        for (i = 0; i < files.length && isValid; ++i) {
          fileType = files[i].type.split('/');
          isValid = false;
          for (j = 0; j < types.length && !isValid; ++j) {
            acceptType = types[j];
            isValid = acceptType[0] === fileType[0] && (acceptType[1] === '*' || acceptType[1] === fileType[1]);
          }
        }
      }
      ctrl.$setValidity('file', isValid);

      var viewValue;
      if (isValid) viewValue = attr.multiple ? files : files[0];
      ctrl.$setViewValue(viewValue);
    });
  });
}

+1

+1

@ntrp 이 변경 사항을 홍보하지 않으시겠습니까?

그 변경 사항은 조금 더 정교하고 테스트해야 합니다. 지금은 그렇게 할 시간이 없습니다.

+1

+1

-1:트롤페이스:

농담 +1

+1

+1

+1

+1

+1

모든 대상 브라우저에서 사용할 수 없는 File API를 명시적으로 사용하지 않는 한 input[type=file]은 실제로 양방향 바인딩이 아닙니다. 이것을 ng-model에 추가하는 것은 의미가 없지만 이 기능의 일부 변형을 지원하는 플러그인이 많이 있습니다. 잠시 동안 이것을 플러그인에 위임하는 것이 좋지 않습니까?

http://caniuse.com/fileapi

@caitp 맞습니다. 하지만 작동하지 않는 ng-change를 통해 변경 이벤트에 바인딩할 수 있다는 것은 의미가 있습니다.

작동하지 않는 또 다른 것은 양식 유효성 검사입니다. 이전 브라우저에 대한 단방향 데이터 바인딩 폴백과 함께 새 브라우저에 대해 파일 지원이 구현되어야 한다고 생각합니다. 이 솔루션이 실행 가능하지 않다면 제 생각에는 기능이 구현되지 않은 이유와 지원 부족으로 인해 발생하는 문제를 해결하는 방법을 위키에 명확하게 명시해야 합니다. 처음 사용할 때 입력 파일 요구 사항을 해결하기 전에 많은 시간을 허비했던 것을 기억합니다.

문제는 파일 이름이 모델에 바인딩되지 않고 모델에 바인딩하는 것이 실제로 의미가 없다는 것입니다. File 인터페이스의 모든 속성은 읽기 전용이며 FileList 인터페이스는 파일 모음일 뿐입니다. 양방향 바인딩을 위한 용량이 없으므로 애초에 ng-model을 사용할 이유가 없습니다. 대신 change 이벤트에 바인딩하는 것은 간단하며, 필요한 경우 선언적으로 사용할 수 있도록 해당 기능을 추가하는 지시문을 쉽게 작성할 수 있습니다.

그러나 ng-model 동작을 따를 수 있는 능력이 없을 때 이것을 ng-model의 일부로 만드는 것이 어떻게 의미가 있습니까?

파일에 대한 사용자 정의 인터페이스를 만들 수 없는 이유는 없으며 Angular가 어느 시점에서 이를 수행할 수 있지만 제 생각에는 ng-model에는 실제로 의미가 없습니다. 다른 개발자들이 이에 대해 어떻게 생각하는지 모르겠지만 동의할 수도 있고 동의하지 않을 수도 있습니다. 그러나 내 관점에서는 input[type=file] 이 ng-model에 맞지 않기 때문에 별도의 지시문이 더 합리적입니다.

  • 파일 입력 값에 대한 내용은 스크립트 컨텍스트에서 쓸 수 없습니다.
  • File API(여러 대상 브라우저에서 지원되지 않음) 없이 여기에서 유효성 검사를 수행할 실제 방법이 없습니다. 기본적으로 브라우저는 이 작업을 수행합니다. --- ngRequired 유효성 검사를 제외하고

input[type=file]에 대해 우리가 실제로 할 수 있는 유일한 것은 값이 변경될 때 $setViewValue이고(이는 실제로 의미가 없음), 어떻게든 ngModel을 변경하여 스크립트 변경으로 인한 모델 값 변경을 무시하도록(또는 기본적으로 $watch를 완전히 비활성화하십시오). 유효성 검사와 관련하여 우리가 실제로 지원할 수 있는 것은 ng-required뿐입니다. 여기서 우리가 할 수 있는 다른 일은 무엇입니까?

ngModel로 파일 입력도 지원하고 싶지만 어떻게 작동하는지 알 수 없고 ngModel 인터페이스에 맞지 않을 뿐입니다.

나는 이 말에 동의하지만, 앞서 말했듯이 개발자가 필요한 기능을 달성하기 위해 무엇을 해야 하는지 알 수 있도록 위키나 일반적으로 문서에서 이에 대해 더 강조해야 합니다.

@ntrp well docs 패치는 환영할 일이며 제출하면 기꺼이 검토하겠습니다. :)

Angular 자체에 특정 지시문을 추가하는 것이 해결책이 될 수 있습니까?

나는 앞의 말에 동의하지만 적어도 조금 이상해 보인다.
Angular와 같은 프레임워크는 달성할 명확하고 깨끗한 방법이 없습니다.
이것...
이것은 아마도 내가 시도할 때 직면해야 했던 가장 혼란스러운 일이었을 것입니다.
파일을 올리다...

아 알았어 @caitp , 얼마 전에 위키 풀 요청이 실제로 적극적으로 평가되지 않았다는 것을 읽었으므로 기여하는 데 신경 쓰지 않았습니다. 곧 자유 시간이 생긴다면 기꺼이 기여할 것입니다 :) 감사합니다.

나는 ngChange 지시문이 ngModel도 있어야 한다는 것을 깨닫지 못했습니다. 이것이 여기에서 ngModel에 대한 많은 논의가 있는 이유인 것 같습니다(그리고 이것이 내가 이 오류가 발생하는 이유입니다). input[type=file]에 대한 양방향 바인딩이 의미가 없다는 데 동의합니다.

그러나 ngChange에 ngModel이 필요한 정확한 이유는 무엇입니까? 내 생각에는 input[type=file] 필드의 변경 이벤트에 바인딩할 수 있는 것이 완전히 의미가 있습니다. 예를 들어 파일이 선택되면 양식을 자동 제출하려는 경우와 같습니다. 그런 경우 필드의 값이 무엇인지는 별로 신경 쓰지 않습니다. 나는 단지 그것이 바뀌었다는 것에 관심이 있다. 그런 일을 처리하는 가장 좋은 방법은 위에서 @cztomsik이 언급한 해결 방법을 사용하는 것입니다.

onchange="angular.element(this).scope().fileChangedHandler()"

그리고 그것은 최고의 솔루션처럼 느껴지지 않습니다.

ng-change 는 다른 이벤트 핸들러 지시문과 이름이 비슷하지만 실제로는 change 이벤트에 대한 핸들러가 아닙니다. $setViewValue 가 호출될 때마다 트리거되는 $viewChangeListener 를 ngModelController에 추가합니다.

나는 그것이 불행한 이름이라는 데 동의합니다.

이것은 https://github.com/angular/angular.js/issues/1236#issuecomment -29115377 댓글로 마감된 #1236의 속임수입니다.

가벼우면서도 기능적이며 프레임워크 사용자에게 ux 스타일을 강제로 적용할 필요가 없도록 구현하는 방법에 대한 제안을 보지 않는 한 고려할 것입니다. 그러나 지금 우리는 파일 업로드 문제가 충분히 복잡하여 코어 외부에 있을 가능성이 있는 searate 모듈로 해결해야 한다고 생각합니다.

+1

@IgorMinar 는 약간 더럽지만 매우 흥미로운 구현 예인 https://github.com/danialfarid/angular-file-upload를 살펴보세요 @danialfarid 는 이를 통해 큰 발전을 이루고 있습니다.

여러 의견으로 여러 문제가 열렸고 모든 문제가 어떻게 문제인지 확인하십시오. 당신은 우리를 위해 ngUpload 모듈을 제공해야 합니다: smile:. html5 구현을 제공하고 https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills#file -api 와 함께 사용 예제를 http://docs.angularjs.org/guide에 추가할 수 있습니다.

어떻게 해결할 생각입니까?

+1

+1

+1

+1

+1

+1

+1

+1

와, 이 단계에서 좀 부끄럽네요.

+1

파일 입력에 대해 양방향 바인딩을 갖는 것은 실제로 불가능합니다. 대상 브라우저가 모두 파일 API를 지원하지 않는 경우(http://caniuse.com/fileapi) --- 하지만 가능하더라도 input[type=file] 는 어쨌든 그것에 적합하지 않습니다. 양방향 바인딩은 정말 불가능합니다.

죄송합니다만 이것은 무엇보다 웹 플랫폼의 문제/보안 기능입니다. 할 수 있었다면 이루어졌을 것이다.

@caitp 나는 당신이 말하는 것을 완전히 이해하지만 "이것은 다른 무엇보다 웹 플랫폼의 문제/보안 기능에 가깝습니다"는 약간 우스꽝스러운 진술입니다. 프레임워크의 요점은 브라우저의 단점, 웹 사양 및 다양한 불일치를 용이하게 하는 것입니다. 이것은 확실히 fileAPI에 대한 경고가 적절한 한 곳입니다. 이제 솔루션이 있습니다. 접으십시오.

래퍼로 간단하게 뭔가 예는 시작이 될 것입니다.

Angular 2.0이 향하고 있는 방향(각도 전용, ECMA가 아닌 관용구 변환)을 감안할 때 "웹 플랫폼"의 제한이 문제가 되어야 한다고 생각하지 않습니다.

@everyone other : 이 경우 Ember는 어떻게 합니까?

편집: 변환 문에서 "필수"를 제거합니다.

_간단한 설명입니다._ Angular 2.0 앱을 빌드하는 데 변환된 언어나 ECMA가 아닌 관용구가 필요하지 않습니다. 일반 ES5 코드를 잘 사용할 수 있습니다. Angular 2.0 소스를 빌드하려면 traceur를 사용하여 컴파일해야 합니다. 당연히 traceur를 사용하여 자체 앱을 빌드하고 Angular 내부에서 사용하는 것과 동일한 기능을 활용할 수 있지만 이는 전적으로 선택 사항입니다. 공지 사항에 혼란이 있었다면 죄송합니다.

@EisenbergEffect 내 나쁜. 나는 그것을 알고 있었고 더 잘 교정했어야 했다. 커피가 없다!

프레임워크는 웹 플랫폼의 한계를 실제로 극복할 수 없습니다. 예를 들어, 브라우저가 읽기 전용 IDL 속성(파일에 대한 양방향 바인딩을 실제로 중단함)에 쓰도록 강제할 수 없으며 브라우저가 파일 시스템을 우리에게 노출하도록 강제할 수 없습니다. 그것으로 흥미로운 무엇이든

@caitp 저는 이 문제를

아마도 우리는 이 대화를 "각도가 이것을 어떻게 지원할 수 있습니까?"로 방향을 바꿀 수 있습니다. 대신 "현재 패턴에 맞지 않을 것입니다."

파일 입력에 바인딩하는 것은 확실히 가능합니다. 실제로 AngularJS에 대한 이전 프로젝트에서 수행했습니다.

파일 입력과 양방향 바인딩할 수 없다는 사실은 보안 기능이며 이는 의미가 있습니다. 작성자는 스크립트를 통해 파일 경로를 설정할 수 없지만 단방향 바인딩은 왜 안 될까요?

물론 그것은 패러다임을 깨뜨립니다. 그러나 해킹 없이 파일 API를 통해 파일에 액세스할 수 있는 능력과 ng-change를 얻는다는 것을 의미한다면 누가 정말로 신경을 쓰겠습니까? jQuery는 파일 입력의 변경 이벤트에 바인딩할 수 있습니다. Angular 방식이 너무 신성해서 컨트롤러 내에서 바인딩할 수 없습니까? 아키텍처의 기술적 한계입니까, 아니면 이념적 장벽입니까?

동의합니다. 양방향 바인딩에 대해 덜 걱정했습니다. 나는 단순히 후프를 건너 뛰지 않고 내 문서의 나머지 부분과 함께 파일을 게시하고 싶었습니다.

오전 7시 53분 5 월 (20), 2014 년에, 저스틴 Arruda < [email protected] [email protected] > 썼다 :

@c aitphttps : //github.com/caitp 내가 지금 얼마 동안이 문제를 다음 왔습니다. 간단한 파일 선택 입력을 지원하기 위해 Angular에 대한 커뮤니티의 요구가 충분하다고 생각합니다. 현재 (내가 실수하지 않는 한) Angular를 사용하여 파일을 수락하고 XHR을 통해 업로드하는 간단한 앱을 빌드하는 데 따라야 할 공식 패턴이 없습니까? "양방향 바인딩이 여기에서 의미가 없기 때문에 할 수 없습니다."

아마도 우리는 이 대화를 "각도가 이것을 어떻게 지원할 수 있습니까?"로 방향을 바꿀 수 있습니다. 대신 "현재 패턴에 맞지 않을 것입니다."


바로이 이메일에 회신 또는 승기에서 볼 tHubhttps : //github.com/angular/angular.js/issues/1375#issuecomment -43636326.

그런 다음 ng-model이 하나의 특정 양식 컨트롤에 대해 크게 다르게 동작하는 한 가지 경우가 있으며 "값을 "foobarblah.txt"로 변경할 때 양식 컨트롤이 잘못된 파일을 보내는 이유는 무엇입니까? 일관되지 않은 API -> 불량입니다.

ngModel은 특히 우리가 맞출 특정 패턴이 있고 애플리케이션 작성자가 끄기가 매우 어렵기 때문에 이 항목에 완전히 이상적이지 않습니다. angular.dart 및 v2.0.0 프로토타입에 이에 대한 솔루션이 있으므로 앞으로는 더 좋아질 것입니다. 그러나 우리는 ng-model이 현재 하는 모든 것을 무시하는 또 다른 ng-model 동작을 추가할 수 없습니다.

파일을 수락하고 Angular를 사용하여 XHR을 통해 업로드합니다.

@guruward 사람들이 충격파 폴리필 또는 이와 유사한 것을 사용하도록 강요하지 않고는 1.x용 모든 대상 브라우저에서 이를 지원할 수 없습니다. 이를 허용하는 타사 모듈이 있으며 대신 사용할 수 있습니다. angular-file-upload는 shockwave polyfill 및 html5 기본 버전을 동시에 제공하고 올바른 버전을 선택합니다. 따라서 이것은 나쁜 솔루션이 아니므로 이 작업을 수행하려는 경우 강력히 권장됩니다.

하지만 핵심에 넣을 수 있는 것인지 확실하지 않습니다. Igor에게 충격파 폴리필을 코어에 탑재하는 것에 대해 어떻게 생각하는지 물어봐야 합니다.

사람들이 절대 하고 싶어하지 않는 사용 사례라고 말하는 것이 아닙니다. 이렇게 하고 싶은 것을 이해할 수 있습니다. 단순히 ngModel 패턴에 맞지 않으며 모든 대상 브라우저를 지원하므로 프레임워크를 그런 식으로 중단합니다.

이를 위해 타사 모듈을 사용하면 어떤 피해가 있습니까?

이 폴리필 은 플래시가 필요하지 않습니다.

@jreading 폴리필 이 아니며 플래시 업로더와 함께 제공되는 데 사용되었지만 여전히 어딘가에 있을 것입니다.

이것이 하는 일은 모든 대상 브라우저에서 사용할 수 없는 파일 API에 의존하는 것이므로 Angular 1.x 코어에 문제가 있습니다.

해당 API가 없으면 Shockwave와 같은 것이 없이는 파일 BLOB에 접근할 수 없습니다.

플래시 대신 iframe을 사용 합니다 .

@jreading 불행히도 이것은 여전히 ​​지원되는 IE9를 포함하여 API를 지원하지 않는 브라우저에는 도움이 되지 않습니다. 지원되는 브라우저 A에서는 작동하지만 IE9 지원에 의존하는 사람들을 위한 해결 방법 없이 코어에서 지원되지 않는 브라우저 B에서는 작동하지 않는 API를 제공할 수 없습니다. 그리고 아니오, iframe은 파일의 내용을 blob으로 노출하지 않고 업로드 가능하게 만듭니다. ㅋㅋㅋㅋ

응용 프로그램이 적합하다고 생각하는 경우 사용할 수 있는 타사 모듈에 이에 대한 솔루션이 있습니다. 이것을 핵심 A)에 넣으면 타사 모듈이 더 어려워지고 B) 모든 대상 브라우저를 지원하지 못하므로 이것이 문제입니다.

이것은 제 생각일 뿐이며, 이고르나 다른 사람이 동의하지 않을 수도 있지만 저는 이것이 올바른 접근 방식이라고 생각하지 않습니다.

타사 모듈이 귀하에게 적합하고 필요한 경우 사용하면 어떤 피해가 있습니까?

컨트롤러에서 Blob을 사용할 수 있어야 한다는 의미는 절대 아닙니다. 나는 사지에 나가지만 내가 본 가장 큰 사용 사례는 파일 입력이 변경된 시점을 아는 기능과 이 iframe 솔루션 또는 파일 API 및 Angular에서 사용할 수 있는 나머지 끝점으로 보내는 기능입니다. 해킹.

타사 모듈은 내 블로그 게시물 (업로드 없음!!)과 같은 유일한 방법이거나 공격적인 개선 사항이지만, 저는 그냥 질문을 돌려 "현대 브라우저에 더 나은 API를 사용하는 것이 해가 되는 것은 무엇입니까?"라고 물을 수 있습니다.

"최신 브라우저에 더 나은 API를 사용하는 것이 무슨 해가 될까요?"

이 주장은 기회 비용을 고려하지 않기 때문에 약합니다. 우리(핵심 팀)가 작업해야 할 다른 많은 것들이 있습니다.

그럴 수 있지. 거대한 간격과 낮은 매달린 과일처럼 느껴집니다.

여기서 문제는 ngModel에서 이 작업을 수행하는 방법에 관한 것이 아닙니다. ngModel이 입력 필드의 FileList를 범위로 노출할 수 있다고 생각하지만 다른 방향에서는 모델을 null/undefined로 설정하는 것만 지원하도록 허용할 것입니다. 파서/포매터는 아무 것도 하지 않고 유효성 검사기는 파일 존재 여부 확인과 같은 간단한 작업만 수행합니다.

문제는 (이전에 언급한 바와 같이) 파일 API 지원 없이는 이 작업을 적절하게 수행하는 것이 우리의 기준선이 IE9이고 이 항목을 폴리필하는 것이 코어에 대해 문제가 되지 않는 경우 코어에 대해 실행 불가능하다는 것입니다.

또한 브라우저 간 호환이 되지 않는 방식으로 이 입력을 처리하려고 하면 타사 솔루션이 더 어려워질 뿐이며 이제 핵심 솔루션과 싸우거나 비활성화하거나 해결해야 합니다.

이를 처리하는 비핵심 솔루션이 이미 존재하며 이 문제 토론과 이전 문제 에서 언급되었습니다.

우리가 끝내고 싶은 더 큰 영향을 미치는 다른 많은 것들이 있습니다. 비교적 흔한 경우라는 것을 알고 있지만 기존 솔루션이 왜 충분하지 않은지 아직 듣지 못했습니다.

이 논의에 투입되는 에너지 중 일부가 필요하다면 기존 솔루션을 개선하거나 기존 솔루션보다 우수한 새로운 솔루션을 만드는 데 사용할 수 있습니까?

우리가 #1236을 닫았던 것처럼 이것을 닫을 것입니다. Angular 2는 최신 브라우저를 지원하도록 구축 중이며 해당 파일 지원을 통해 쉽게 사용할 수 있습니다.

요소에 직접 액세스하고 파일 정보를 가져오고 AJAJ를 통해 업로드할 수 있도록 변경 이벤트가 발생하는 시점을 알고 싶습니다.

@bjoshuanoah 그렇다면

@caitp 지시문이 아닌 컨트롤러의 모든 것을 제어하고 싶습니다.

ng-change="uploadFile({$event: $event})"을 넣으면

내 컨트롤러에 $scope.uploadFile(event)이 있을 수 있습니다. 거기에서 처리하십시오.

내 특정 사용 사례는 다음과 같습니다. s3에 파일 업로드, 내 모델에 URL 적용.

대신 동일한 작업을 수행하기 위해 범위에 침입해야 합니다. 매우 성가시다:

<input name="highRes" scope="{{contentOptions.currentValue}}" key="value" type="file" onchange="angular.element(this).scope().setFile(this)">

누가 이 문제를 죽여줬으면 좋겠다. 우리 모두가 나아갈 수 있도록 :)

2014년 7월 25일 오전 9시 22분에 Brian < [email protected] [email protected] >이(가) 다음과 같이 썼습니다.

요소에 직접 액세스하고 파일 정보를 가져오고 AJAJ를 통해 업로드할 수 있도록 변경 이벤트가 발생하는 시점을 알고 싶습니다.


이 이메일에 직접 답장하거나 Gi tHubhttps://github.com/angular/angular.js/issues/1375#issuecomment -50171714에서 확인하세요.

+1

+1

+1000000000000000

+1

+1

+1

+1

+100500

+1
Ajax가 왜 문제인지 잘 모르겠습니다. 로컬 머신의 csv 파일에서 Angular 모델로 데이터를 로드할 수 있습니다. ng-change가 Angular 내의 파일 입력에서 작동했다면 이것은 쉬울 것이지만 현재 . 이 시나리오에는 Ajax나 서버 API가 전혀 필요하지 않습니다. 나는 이것이 왜 닫혀 있는지 잘 모르겠습니다.

현재 해결 방법은 다음을 수행하는 것입니다.

 input(type="file", onchange="angular.element(this).scope().onFileSet(this.files)")

내 컨트롤러에는 다음과 같은 것이 있습니다.

$scope.onFileSet = function(files) { 
// work your magic here 
}

꽤 악취가 나는데, 내가 앵글을 도구로 욕먹이는 것 같은 느낌이 듭니다. 더 각진 방식으로 이 작업을 수행하는 방법에 대한 통찰력은 매우 감사할 것입니다.

:하트: :하트:

여기 범선이 있습니다: :범선:

@samccone 디버그 모드가 꺼져 있으면 scope()를 사용할 수 없습니까?

@geetsce 맞습니다(1.3.x 이상에서)

웰프, 1.2 랜드에서는 모든 것이 잘됩니다.

@Narretz 더 나은 솔루션이 있습니까?

이것은 저에게 효과적이며 https://jasonturim.wordpress.com/2013/09/01/angularjs-drag-and-drop에서 영감을 받았습니다.

<input type="file" multiple="multiple" data-dbinf-on-files-selected="chooseAFunctionName(selectedFileList)">
<script>
/**Directive to propagate selected files from an HTML input element with type="file"
 * to the surrounding AngularJS controller.
 */
myApp.directive('dbinfOnFilesSelected', [function() {
    return {
        restrict: 'A',
        scope: {
              //attribute data-dbinf-on-files-selected (normalized to dbinfOnFilesSelected) identifies the action
              //to take when file(s) are selected. The '&' says to  execute the expression for attribute
              //data-dbinf-on-files-selected in the context of the parent scope. Note though that this '&'
              //concerns visibility of the properties and functions of the parent scope, it does not
              //fire the parent scope's $digest (dirty checking): use $scope.$apply() to update views
              //(calling scope.$apply() here in the directive had no visible effect for me).
            dbinfOnFilesSelected: '&'
        },
        link: function(scope, element, attr, ctrl) {
            element.bind("change", function()
            {  //match the selected files to the name 'selectedFileList', and
               //execute the code in the data-dbinf-on-files-selected attribute
             scope.dbinfOnFilesSelected({selectedFileList : element[0].files});
            });
        }
    }
}]);

myApp.controller('myController', ['$scope', function($scope) {
    $scope.chooseAFunctionName = function (filelist) {
        for (var i = 0; i < filelist.length; ++i) {
            var file = filelist.item(i);
            //do something with file; remember to call $scope.$apply() to trigger $digest (dirty checking)
            alert(file.name);
           }
    };
}]);
</script>

+1

+1

그런 일은 없을 거야... 놔둬, 놔둬...

+1

@samccone이 말했듯이,

input(type="file", onchange="angular.element(this).scope().onFileSet(this.files)")

이것은 일을 하는 Angular 방식이 아닙니다. 이상해

+1

+1

+1

@caitp @Narretz 여러분이 1.2x 브랜치에 대한 PR을 작성하고 싶다면 이것이 추가하고 싶은지 아닌지 알려주십시오. 실제 파일 개체에 대한 액세스 권한을 얻는 한 보안 문제와 브라우저 간 지원 부족을 이해하지만 파일 입력이 변경된 시점(원래 이벤트 전달)을 감지하기 위한 기본 지원이 충분한 후크를 제공하는 것처럼 보입니다. 사람들이 마법을 부리기 위해.

당신이 하는 모든 것에 다시 한 번 감사드립니다 :palm_tree:

+1

+1

+1

+1

+1

ng-file-upload 가 잘 작동합니다.

@neokyol에 +1!! 그것은 잘 작동합니다!

이 공통 기능은 기본적으로 프레임워크에 있어야 합니다.

도움이되는

+1

+1

+1

+1

+1

이것은 나를 위해 일했으며 도움이 될 수 있습니다.

angular.module('app', [])
  .controller('MainCtrl', MainCtrl)
  .directive('fileChange', fileChange);

  function MainCtrl($scope) {
    $scope.upload = function () {
      // do something with the file
      alert($scope.file.name);
    };
  }

  function fileChange() {
    return {
      restrict: 'A',
      require: 'ngModel',
      scope: {
        fileChange: '&'
      },
      link: function link(scope, element, attrs, ctrl) {
        element.on('change', onChange);

        scope.$on('destroy', function () {
          element.off('change', onChange);
        });

        function onChange() {
          ctrl.$setViewValue(element[0].files[0]);
          scope.fileChange();
        }
      }
    };
  }
<div ng-app="app" ng-controller="MainCtrl">
  <input type="file" file-change="upload()" ng-model="file">
</div>

http://plnkr.co/edit/JYX3Pcq18gH3ol5XSizw?p=preview

+1

+1

+1

+1

+1000000000000000000000000

+1

+1

@dciccale plunker 예제를 제공해 주시겠습니까?

+1

+1

+1 이를 위한 핵심 라이브러리에 지시문이 내장되어 있어야 합니다. 꽤 웃기다

+1

+1
기능이 다음 릴리스 중 하나로 예정되어 있습니까?

+1

+1

$scope가 컨트롤러에 주입되지 않는 프로젝트에서 이 작업을 수행하는 방법입니다. 컨트롤러를 선언하는 GULP 및 ES6 방식을 사용하는 laravel angular를 사용하고 있습니다.

class TestController{
    constructor(API){
        'ngInject';
        this.API = API
    }

    $onInit(){
        this.file = null;
    }
    upload() {
        console.log(this.file)
    }
    fileChanged(elm) {
        console.log('hey')
        this.file = elm.file;
        this.$apply();
    }
}

export const TestComponent = {
    templateUrl: './views/app/components/test/test.component.html',
    controller: TestController,
    controllerAs: 'vm',
    bindings: {}
}

나는 내가 믿는 주위에 일을 찾았습니다. http://stackoverflow.com/questions/38449126/how-to-set-up-ng-file-upload-in-laravel-angular-project/38486379#38486379

+1

@ntrp @guruward @coli @lgersman @jgoldber @Siyfion
에 대한 유효성 검사를 어떻게 수정했습니까?
내 확인:
this.catalougeForm = this.catalougeFormBuilder.group({
카탈로그 아이콘 이름: ['',Validators.required]
});
HTML:
(change)="changeListener($event)">

내 유효성 검사기는 내가 업로드한 후 catalougeIconName 값을 비어 있거나 null로 간주하고 있습니다.
이미지가 전송되고 있지만 유효성 검사기가 작동하지 않습니다.

이에 대한 업데이트가 있습니까?

업데이트가 있습니까?

이 페이지가 도움이 되었나요?
0 / 5 - 0 등급