AngularJS: ngModel с ngSwitch, не можете смотреть?

Я пытаюсь сделать очень простую форму регистрации, которая должна работать в 2 этапа.

  • Я прошу пользователя для его электронной почты на первом этапе
  • на втором шаге я спрашиваю пользователя о других деталях (шаг == 2).

Шаблон прост;

<div class="input-group layout-container" ng-switch on="step">
    <!-- Login -->
    <img src="images/yeoman.png">
    <p>{{msg}}</p>
    <form name="signup">
        <input type="text" class="form-control login" placeholder="firstname" ng-model="firstname" ng-switch-when="2">
        <input type="text" class="form-control login" placeholder="lastname"ng-model="lastname" ng-switch-when="2">
        <input type="email" class="form-control login" placeholder="email" ng-model="email" ng-switch-when="1" required>
        <span class="error" ng-show="signup.input.$error.required">Cannot be blank</span>
        <span class="error" ng-show="signup.input.$error.email">Not a valid email</span>
        <input type="password" class="form-control login" placeholder="password" ng-model="pass" ng-switch-when="2"> <br/><br/>
        <div class="btn-container">
            <button class="btn btn-primary" ng-click="next()">Next</button>
        </div>
    </form>
</div>

Как вы можете видеть, также происходит некоторая базовая проверка, и я присваиваю значение электронной почты модели, которую я называю электронной почтой.

И контроллер выглядит так:

.controller('SignupCtrl', function ($scope) {
    $scope.msg = "First, your email";
    $scope.step = 1;
    $scope.email = ''; // this still doesn't help
    $scope.$watch('email', function (now, then, scope) {
        console.log('email change', now, then);
    });
    $scope.next = function () {
        $scope.step = Math.min($scope.step + 1, 2);
    };
})

Проблема в том, что $watch на 'email' вообще никогда не срабатывает. Где это идет не так?

2 ответа

Решение

Вот работающий jsfiddle (только той части, с которой у вас проблемы): demo

function ctrl($scope) {
    $scope.items = ['one','two'];
    $scope.selection = 'two';
    $scope.data = {email:''};
    $scope.$watch('data.email', function (now, then, scope) {
        console.log('email change', now, then);
    });
}

Обратите внимание, что он будет запускать часы только в том случае, если адрес электронной почты действителен, если ввод type="email",

Редактировать: обновлено для использования с ng-switch.

Объяснение: Как отмечает miqid, когда вы используете примитивы, дочерние области не имеют доступа к родительским переменным области действия, но когда они являются объектами angular, создается ссылка в дочерних областях.

Я согласен с @miqid, что ng-switch создает новую область неявно. Все изменения стоимости <input> на самом деле произошло в этой изолированной дочерней области. Его родитель, где вы делаете $watch, не будут уведомлены. Вот почему вы не можете наблюдать за изменениями переменных. Это распространенная ловушка для угловых пользователей.

LT; DR просто поменяй любой ng-model="foo" в ng-model="$parent.foo" в вашем ng-switch блок.

Другие вопросы по тегам