Вопрос

Ok, so I am creating a form like so:

<form novalidate class="simple-form" action="" name="mainForm" ng-submit="doSubmit()" method="POST">
    <div ng-form name="giftForm" class="panel-body">
         <input type="text"
                   id="x_amount"
                   name="x_amount"
                   class="form-control input-lg"
                   ng-model="giftForm.amount"
                   ng-required="true">
    </div>
    <div class="row">
        <button type="submit" class="btn" ng-disabled="mainForm.$invalid">Submit</button>
    </div>
</form>

This works for validation, i.e. that mainForm.$invalid only highlights enables the button after the input has text. However, using batarang, I noticed that the scope looks like so:

{"giftForm":{"x_amount":{},"amount":"a"}}

So it is creating model values based on the name and the declared ng-model. If I change them to be the same like so:

<input type="text"
                   id="x_amount"
                   name="x_amount"
                   class="form-control input-lg"
                   ng-model="giftForm.x_amount"
                   ng-required="true">

The submit shows the correct scope of:

{"giftForm":{"x_amount":"a"}} 

But the input field initially shows with [Object object] in the input, which makes me think I am confusing something here..... I can't have that in all of the input fields.

I'd like the name and the model to be the same. That would seem to be the progressive enhancement way and would allow a normal non-ajax post by simply removing the ng-submit method and the ajax way would look like:

$http({
         method  : 'POST',
         url     : 'formAction.do',
         data    : $.param(angular.toJson($scope.mainForm)),
         headers : { 'Content-Type': 'application/x-www-form-urlencoded' }  
            })
                .success(function(data) {
                   //success
                })
                .error(function(data, status, headers, config) {
                    //error
                });

Anybody has insight into what I am missing or if my architecture is flawed from the ground-up, I'd appreciate the wisdom....

Это было полезно?

Решение

Naming a form places a variable in scope with that name. Under it, it puts properties named after the form fields names. However, you already have a model in the scope with the same name as the form: giftForm. This causes confusion: the template overwrites the model and/or vice versa.

So, give another name to one of them, eg name the model giftModel.

Другие советы

I'd like the name and the model to be the same.

You could do that, but you'd have to have a separate scope, and therefor a separate controller for your form.

More importantly, though, this isn't going to buy you anything. The input name attributes are primarily used for validation display, and not much else.

Your use of $http concerns me more. It looks like you're thinking in a JQuery mindset. I'd challenge you to throw JQuery out the window for a while until you get used to Angular.

Here's what people generally do with forms (From the model structure to the naming and validation):

View:

<form name="myForm" ng-submit="sendFoo()">
   <div>
      <label for="name">name</label>
      <input type="text" id="name" name="name" ng-model="foo.name" required/>
      <span ng-show="myForm.name.$error.required">required</span>
   </div>
   <div>
      <label for="email">email</label>
      <input type="email" id="email" name="email" ng-model="foo.email" required/>
      <span ng-show="myForm.email.$error.required">required</span>
      <span ng-show="myForm.email.$error.email">invalid email</span>
   </div>
   <button type="submit" ng-disabled="myForm.$invalid">Submit</div>
</form>

Controller:

app.controller('MyCtrl', function($scope, $http) {
   $scope.foo = {
       name: 'Someone Special',
       email: 'test@monkey.com'
   };    

   $scope.sendFoo = function (){
      $http.post('/Some/Url/Here', $scope.foo)
          .then(function(result) {
             $scope.result = result.data;
          });
   });
});

You'll notice that the name of the form and the names of the inputs are only used for validation on those <span> tags. Like so: <span ng-show="[formName].[fieldName].$error.[validationName]">invalid message</span>. That object is available on the $scope at $scope.formName, but there usually isn't a reason to access it directly in your controller.

I hope this helps you (or someone).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top