Ng-repeat по свойствам объекта, но дефокусирует поле ввода после ввода

Я использую ng-repeat для привязки элементов формы к свойствам настраиваемого объекта, который у меня есть, например:

 $scope.myObject = {
            'font-size': 10,
            'text-outline-width': 2,
            'border-color': 'black',
            'border-width': 3,
            'background-color': 'white',
            'color': '#fff'
    }

HTML:

<div ng-repeat='(key, prop) in myObject'>
    <p>{{key}} : {{prop}}</p>
    <input type='text' ng-model='myObject[key]'>
</div>

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

Есть ли другой способ сделать это двустороннее связывание с объектом, чтобы я мог свободно вводить?

Вот JSFiddle: http://jsfiddle.net/AQCdv/1/

Ответ 1

Вводы причин были не сфокусированы, так это то, что Angular перестроил DOM при каждом изменении myObject. Вы можете специально указать ng-repeat для отслеживания по ключу, поэтому нежелательного поведения не произойдет. Кроме того, для версии 1.1.5 потребуется более новая версия библиотеки:

function MyCtrl($scope) {
  $scope.myObject = {
    'font-size': 10,
    'text-outline-width': 2,
    'border-color': 'black',
    'border-width': 3,
    'background-color': 'white',
    'color': '#fff'
  }
}
<script src="http://code.angularjs.org/1.1.5/angular.min.js"></script>
<div ng-app ng-controller="MyCtrl">
  <div ng-repeat='(key, prop) in myObject track by key'>
    <p>{{key}} : {{prop}}</p>
    <input type='text' ng-model='myObject[key]'>
  </div>
</div>

Ответ 2

это можно решить с помощью директивы. Я создал директиву под названием customBlur, но ее можно назвать любым, что вам нужно, если она соответствует вашему HTML. Посмотрите скрипку здесь: http://jsfiddle.net/AQCdv/3/

angular.module('app', []).directive('customBlur', function() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, elm, attr, ngModelCtrl) {
            if (attr.type === 'radio' || attr.type === 'checkbox') return; //ignore check boxes and radio buttons

            elm.unbind('input').unbind('keydown').unbind('change');
            elm.bind('blur', function() {
                scope.$apply(function() {
                    ngModelCtrl.$setViewValue(elm.val());
                });
            });
        }
    };
});

и директива HTML, которая будет использоваться как

<input type='text' ng-model='myObject[key] ' custom-blur>

То, что эта директива делает, - это отменить события, которые производят обновления модели, которые заставляют ваше текстовое поле терять фокус. Теперь, когда текстовое поле теряет фокус (событие размытия), модели обновляются.