ProgramingTip

지시문에 양식 전달

bestdevel 2020. 10. 25. 12:45
반응형

지시문에 양식 전달


이 작업을 수행 할 수있는 양식 필드를 지시문에 캡슐화하고 싶습니다.

<div ng-form='myForm'>
  <my-input name='Email' type='email' label='Email Address' placeholder="Enter email" ng-model='model.email' required='false'></my-input>

</div>

myForm유효성 검사를 수행 할 수 있도록 지시문에서 액세스 순서대로해야 myForm.Email.$valid합니까?


지시문에서 FormController에 액세스하려는 경우 :

require: '^form',

다음 링크 함수의 네 번째 인수로 사용할 수 있습니다.

link: function(scope, element, attrs, formCtrl) {
    console.log(formCtrl);
}

fiddle

하지만 NgModelController에 대한 액세스 만 필요할 수 있습니다.

require: 'ngModel',
link: function(scope, element, attrs, ngModelCtrl) {
     console.log(ngModelCtrl);
}

fiddle

두 가지 모두에 액세스해야하는 경우 :

require: ['^form','ngModel'],
link: function(scope, element, attrs, ctrls) {
    console.log(ctrls);
}

fiddle


다음은 완전한 예입니다 (Bootstrap 3.1을 사용하여 스타일 지정됨).

여기에는 여러 입력 (이름, 이메일, 나이 및 국가)이있는 양식이 포함되어 있습니다. 이름, 이메일 및 나이는 지침입니다. 국가는 "일반"입력입니다.

사용자가 올바른 값을 입력하지 않고 각 입력에 대해 도움말 메시지가 표시됩니다.

양식에 하나 이상의 오류가있는 경우 사용할 수없는 저장 버튼이 있습니다.

<!-- index.html -->
<body ng-controller="AppCtrl">
  <script>
    var app = angular.module('app', []);

    app.controller('AppCtrl', function($scope) {
      $scope.person = {};
    });
  </script>
  <script src="inputName.js"></script>
  <script src="InputNameCtrl.js"></script>
  <!-- ... -->

  <form name="myForm" class="form-horizontal" novalidate>
    <div class="form-group">
      <input-name ng-model='person.name' required></input-name>
    </div>

    <!-- ... -->

    <div class="form-group">
      <div class="col-sm-offset-2 col-sm-4">
        <button class="btn btn-primary" ng-disabled="myForm.$invalid">
          <span class="glyphicon glyphicon-cloud-upload"></span> Save
        </button>
      </div>
    </div>
  </form>

  Person: <pre>{{person | json}}</pre>
  Form $error: <pre>{{myForm.$error | json}}</pre>
  <p>Is the form valid?: {{myForm.$valid}}</p>
  <p>Is name valid?: {{myForm.name.$valid}}</p>
</body>

// inputName.js
app.directive('inputName', function() {
  return {
    restrict: 'E',
    templateUrl: 'input-name.html',
    replace: false,
    controller: 'InputNameCtrl',
    require: ['^form', 'ngModel'],

    // See Isolating the Scope of a Directive http://docs.angularjs.org/guide/directive#isolating-the-scope-of-a-directive
    scope: {},

    link: function(scope, element, attrs, ctrls) {
      scope.form = ctrls[0];
      var ngModel = ctrls[1];

      if (attrs.required !== undefined) {
        // If attribute required exists
        // ng-required takes a boolean
        scope.required = true;
      }

      scope.$watch('name', function() {
        ngModel.$setViewValue(scope.name);
      });
    }
  };
});

// inputNameCtrl
app.controller('InputNameCtrl', ['$scope', function($scope) {
}]);

지시문이있는 AngularJS 양식


편집 2 : 다른 이유에서 도움이 될 수 있기 때문에 대답을 둘 것입니다. 그러나 Mark Rajcok의 다른 대답은 원래 있었지만 일하지. 여기의 부모 분명히 컨트롤러는 form오는가 않습니다 ngForm.


사용하여 지시문의 속성을 사용하여 다소 장황합니다.

다음은 작동하고 단순화 된 jsFiddle 입니다.

암호

HTML :

<div ng-form="myForm">
    <my-input form="myForm"></my-input>
</div>

지침의 필수 부분 :

app.directive('myInput', function() {
    return {
        scope: {
            form: '='
        },
        link: function(scope, element, attrs) {
            console.log(scope.form);
        }
    };
});

무슨 일이야

사용하여를 form속성에 명명 된 범위 값 을 격리 된 범위 에 바인딩하도록 각도 요청 고객에 했습니다 '='.

이렇게하면 입력 지시문에서 실제 형식이 분리됩니다.

참고 :을 사용해 require: "^ngForm"보았지만 ngForm 지시문은 컨트롤러를 정의하지 않으며 그러한 방식으로 사용할 수 없습니다 (너무 나쁩니다).


이 모든 것을 처리하는 데 매우 장황하고 지저분한 방법이라고 생각합니다. 양식 요소에 새 지시문을 추가하고 require해당 항목에 액세스하는 데 사용하는 것이 더 나을 수 있습니다 . 내가 뭔가를 합칠 수 있는지 볼게요.

편집 : 상위 지시문 사용

좋습니다. 부모 지시문을 사용하여 알아낼 수있는 최선의 방법은 다음과 같습니다. 잠시 후에 더 자세히 설명하겠습니다.

부모 지시문을 사용하여 jsFiddle 작업

HTML :

<div ng-app="myApp">
    <div ng-form="theForm">
        <my-form form="theForm">
            <my-input></my-input>
        </my-form>
    </div>
</div>

JS (일부) :

app.directive('myForm', function() {
    return {
        restrict: 'E',
        scope: {
            form: '='
        },
        controller: ['$scope', function($scope) {
            this.getForm = function() {
                return $scope.form;
            }
        }]
    }
});

app.directive('myInput', function() {
    return {
        require: '^myForm',
        link: function(scope, element, attrs, myForm) {
            console.log(myForm.getForm());
        }
    };
});

이렇게하면 부모 지시문 범위 ( myForm)에 양식이 저장되고 부모 양식 ( require: '^myForm') 을 요구 하고 연결 함수 ( myForm.getForm()) 에서 지시문의 컨트롤러에 액세스하여 자식 지시문이 액세스 할 수 있습니다 .

혜택:

  • 한 곳에서 양식을 식별하기 만하면됩니다.
  • 부모 컨트롤러를 사용하여 공통 코드를 저장할 수 있습니다.

부정적 :

  • 추가 노드가 필요합니다.
  • 양식 이름을 두 번 입력해야합니다.

내가 선호하는 것

양식 요소의 속성을 사용하여 작동하도록하려고했습니다 . 이 방법이 효과가 있다면 .NET과 동일한 요소에 지시문을 추가하기 만하면됩니다 ngForm.

그러나 myFormName변수가 내 $scope에서 표시 되지만 undefined액세스하려고 할 때 범위에서 이상한 동작 발생했습니다. 그것은 나를 혼란스럽게 만든다.


AngularJS 1.5.0부터는이를위한 훨씬 더 깨끗한 솔루션이 있습니다 ( link함수를 직접 사용하는 것과 반대 ). FormController하위 구성 요소의 지시문 컨트롤러에 있는 양식에 액세스 하려면 다음 require과 같이 지시문 속성을 간단히 슬랩 할 수 있습니다 .

return {
  restrict : 'EA',
  require : {
    form : '^'
  },
  controller : MyDirectiveController,
  controllerAs : 'vm',
  bindToController : true,
  ...
};

다음으로 다른 범위 변수처럼 템플릿 또는 지시어 컨트롤러에서 액세스 할 수 있습니다. :

function MyDirectiveController() {
  var vm = this;
  console.log('Is the form valid? - %s', vm.form.$valid);
}

이 작업을 수행하려면 bindToController: true지시문에 속성을 설정해야합니다. 참고 항목 문서 에 대한 $compile 자세한 내용은 질문을.

문서의 관련 부분 :

요구하다

다른 지시문을 요구하고 해당 컨트롤러를 연결 함수에 대한 네 번째 인수로 삽입합니다. require 속성은 문자열 , 배열 또는 객체수 있습니다 .

require 속성이 개체 이고 bindToController사실이면 필수 컨트롤러가 require 속성의 키를 사용하여 컨트롤러에 바인딩됩니다. 필요한 컨트롤러의 이름이 로컬 이름 (키)과 같으면 이름을 생략 할 수 있습니다. 예를 들어 {parentDir: '^parentDir'}{parentDir: '^'}.


당신의 '내가 선호하는 것'을 바이올린 작업으로 만들었습니다! 어떤 콘솔 console.log에서 "$ scope.ngForm"문자열을 볼 수 있습니다 직접 로깅이 작동하지 않아 정의되지 않습니다. 그러나 컨트롤러 함수에 속성을 전달하면 얻을 수 있습니다.

app.directive('myForm', function() {
return {
    restrict: 'A',
    controller: ['$scope','$element','$attrs', function($scope,$element,$attrs) {
        this.getForm = function() {
            return $scope[$attrs['ngForm']];
        }
    }]
}
});

http://jsfiddle.net/vZ6MD/20/

참고 URL : https://stackoverflow.com/questions/17618318/pass-form-to-directive

반응형