简体   繁体   中英

Ng-model value is undefined from directive element

I have created a directive which allows the user to toggle a value (gender: male or female) as part of a registration form. The textual value assigned to the input element is being updated within the view when toggled however, the ng-model value is undefined when I submit the form.

I'm pretty sure this has to do with the fact that the element generated via the directive is injected into the DOM after the view is loaded. In jQuery you'd simply target the element after the defining an event type and this would solve the issue, however I am not sure how I can resolve the issue in Angular.

.directive('gendertoggle', function() {
  return {
    restrict: 'E',
    template: '<input type="button" value="Male" ng-model="user.gender"></input>',
    link: function($scope, elem, attrs) {
      elem.bind("click", function() {
        if (elem[0].childNodes[0].value == "Male") {
          elem[0].childNodes[0].value = "Female";
          $scope.gender = 'Female';
          console.log($scope.gender);
        } else {
          elem[0].childNodes[0].value = "Male";
          $scope.gender = 'Male';
          console.log($scope.gender);
        }
      })
    }
  }
});

.controller('RegisterCtrl', function($scope, $ionicHistory, $state, $rootScope, $localstorage, AuthenticationService AUTH_PROVIDER) {
  $scope.RegisterUser = function(user){
    var email = user.email.toLowerCase();
    var firstname = user.firstname;
    var lastname = user.lastname;
    var password = user.password;
    var gender = user.gender;

    console.log(gender); //This is undefined

  }
})


<input type="text" name="firstname" ng-model="user.firstname">
<input type="text"name="lastname" ng-model="user.lastname">
<input type="email" name="email" ng-model="user.email" required>
<input name="password" type="password" ng-model="user.password">
<gendertoggle></gendertoggle>
<button nav-clear ng-click="RegisterUser(user)">
Register
</button>

Well first of all, you don't need to manipulate the value attribute of an input when using ngModel . You should read up in the documentation about this.

To your problem. You're accessing the property gender of the $scope of your controller. (i recommend not using the controllers $scope inside a directive, instead pass everything you need to the directive from your view, and use an isolated scope).

But what you want to target is user.gender . I changed some parts of your code slighthy

.directive('gendertoggle', function() {
    return {
     restrict: 'E',
     scope: {
        user: "=",
     },
     template: '<button ng-click="onClick()">{{user.gender}}</button>',
     link: function(scope, elem, attrs) {
     scope.onClick = function(){
          scope.user.gender = scope.user.gender === "Male" ? "Female" : "Male";
     };
   }
 }
});

.controller('MainCtrl', function($scope) {
    $scope.viewModel = {
      user: {
        email: "",
        firstname: "",
        lastname: "",
        password: "",
        gender: "Male"
      },
      register: function(){
        console.log($scope.viewModel.user);
      }
   }
 });


<input type="text" ng-model="viewModel.user.firstname">
<input type="text" ng-model="viewModel.user.lastname">
<input type="email" ng-model="viewModel.user.email" required>
<input type="password" ng-model="viewModel.user.password">
<gendertoggle user="viewModel.user"></gendertoggle>
<button nav-clear ng-click="viewModel.register()">Register</button>

Hope it helps.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM