Обновление различных свойств объекта $scope с помощью ng-модели

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

Codepen: http://codepen.io/uloco/pen/jboorN

HTML

<div ng-app="app" ng-controller="AppController" class="content">
    <input type="tel" ng-model="form.phone" placeholder="phone" />
    <input type="email" ng-model="form.email" placeholder="email" />
    <p>{{form}}</p>
    <p>{{data}}</p>
</div>

JS

angular
.module('app', [])
.controller('AppController', function($scope) {
    $scope.form = {};
    $scope.data = {
        foo: 'bar',
        phone: $scope.form.phone,
        email: $scope.form.email
    }
});

5 ответов

Решение

Почему переменная $scope.data не обновляется?

Потому что нет никакой связи между $scope.data а также $scope.form, Это два отдельных объекта с независимыми свойствами, и вы меняете свойства $scope.form,

Если вы действительно хотите иметь два отдельных объекта, вам нужно будет синхронизировать их вручную либо с $scope.$watch на $scope.form

$scope.$watch('form', function(obj) {
    $scope.data.phone = obj.phone;
    $scope.data.email = obj.email;
}, true);

Демоверсия: http://codepen.io/anon/pen/PPvvBr?editors=101

или с ngChange директивы:

<input type="tel" ng-model="form.phone" placeholder="phone" ng-change="sync()" />
<input type="email" ng-model="form.email" placeholder="email" ng-change="sync()" />

а также

$scope.sync = function() {
    $scope.data.phone = $scope.form.phone;
    $scope.data.email = $scope.form.email;
};

Демоверсия: http://codepen.io/anon/pen/bVyyQN?editors=101

ngChange Решение является предпочтительным в этом случае. Однако, если у вас более 2 полей, то $watch может быть проще.

Вы можете попробовать добавить ng-change:

 $scope.change = function(data){
        $scope.data.phone = data.phone;
        $scope.data.email = data.email;
    };

и на HTML

<input type="tel" ng-model="form.phone" placeholder="phone" ng-change="change(form);"/>
<input type="email" ng-model="form.email" placeholder="email" ng-change="change(form);"/>

$scope.form.phone и $ scope.form.email назначаются при настройке контроллера, где они оба не определены. Даже если $ scope.form изменяется, $ scope.data не знает, потому что все, что он хранит, является "неопределенным".

Чтобы получить данные, вы можете реализовать такую ​​функцию:

$scope.getData = function () {
    return {
        foo: 'bar',
        phone: $scope.form.phone,
        email: $scope.form.email
    };
};

Это гарантирует, что объект заново инициализируется, когда вам это нужно.

Ваши $scope.data назначаются один раз и не меняются при изменении телефона или электронной почты.

Попробуйте использовать $watchGroup

$scope.$watchGroup(['form.phone', 'form.email'], function(newValues, oldValues, scope) {
  scope.data = {
        foo: 'bar',
        phone: scope.form.phone,
        email: scope.form.email
 }
});

Вы можете использовать HTML

<div ng-app="app" ng-controller="AppController" class="content">
    <input type="tel" ng-model="form.phone" placeholder="phone" />
    <input type="email" ng-model="form.email" placeholder="email" />
    <p>form: {{form}}</p>
    <p>data: {{data()}}</p>
</div>

JS

angular
    .module('app', [])
    .controller('AppController', function($scope) {
        $scope.form = {};
        $scope.data = function() {
            return {
                foo: 'bar',
                phone: $scope.form.phone,
                email: $scope.form.email
            };
        }
    });

обновленный код: http://codepen.io/anon/pen/Xmwwye

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