Эффективный / Единственный триггер ng-изменения в текстовом поле - PullRequest
0 голосов
/ 26 апреля 2019

Допустим, у меня есть следующий массив в угловом контроллере:

somelist = [ 
             { name: 'John',  dirty: false },
             { name: 'Max',   dirty: false },
             { name: 'Betty', dirty: false }
           ];

Я хочу повторить это в моем представлении и сгенерировать редактируемые поля для каждой записи:

<div ng-repeat="i in somelist">
     <input type="text" ng-model="i.name"/>
</div>

Как бы я мог эффективно пометить поле как грязное, если бы кто-то редактировал текстовое поле (модель)?

Я понимаю, что мог бы использовать ng-change для текстового поля, однако он срабатывает каждый раз, когда пользователь вносит одно изменение (ввод ключа) в текстовое поле, делая ненужные загрузки вызовов. Есть ли более эффективный способ сделать это, что мне не хватает?

Ответы [ 2 ]

0 голосов
/ 26 апреля 2019

Чтобы повысить эффективность, уменьшите число наблюдателей , используя :: и исключив двусторонние привязки, например, ng-model:

<div ng-repeat="i in ::somelist"> <input type="text" value="{{i.name}}" ng-blur="$emit('nameChanged', i)"/> </div>

Тогда в вашем контроллере:

$scope.$on('nameChanged', (event, i) => updateName(i));

Затем быстрая, простая функция, которая обновляет имя с соответствующим идентификатором, используя i.id и i.name, при условии, что у вас есть:

$scope.someList = [ { id: 1, name: 'John' }, { id: 2, name: 'Max' }, { id: 3, name: 'Betty }'

Объяснение

Если люди не будут добавлены / удалены из списка, вы можете использовать :: для someList, также известный как одноразовая привязка , для повышения эффективности. Это обходит настройку watcher .

Кроме того, установив значение = {{i.name}}, вы фактически устанавливаете одностороннюю привязку от контроллера к DOM, а не двустороннюю, что означает, что значение входа не ' Проверяется каждый цикл цикла $digest, но любые изменения в модели будут обновлять DOM.

Просто идея, не стесняйтесь играть с вариациями, такими как отбрасывание размытия и использование одной кнопки, которая обновит все измененные поля сразу.

Вы не добьетесь гораздо большей эффективности, если только вы не удалите наблюдателя из value="{{i.name}}", как, например, value="{{::i.name}}", а затем вручную обновите DOM при получении события.

0 голосов
/ 26 апреля 2019

С JavaScript ...
* Отредактировано: если у тех текстовых областей нет другого события 'change' для запуска, вы можете попробовать встроенное событие onchange и заменить его значение после однократного запуска. Просто заставляя onchange="once(this)" стать этим - onchange="" * В фоновом режиме. Код все еще останется в вашем HTML. Демонстрация:

(также существуют input и keyup события ... также в Angular)

function once(e){
  e.style.color="red";
  e.onchange = "";
  
  //just demo... remove this.
  const d = document.getElementById('demo');
  d.innerText = Number(d.innerText) + 1;
 }
<textarea class="moo" onchange="once(this)">Change me!</textarea>
<textarea class="moo" onchange="once(this)">Me too!</textarea>
<textarea class="moo" onchange="once(this)">And me!</textarea>
<br><br>
Triggered times: <span id="demo">0</span>

Запуск функции eventListener один раз (не совсем):

let once = [];//creating empty array
const moo = document.getElementsByClassName('moo');//getting all textareas
for(let i = 0; i < moo.length; i++ ){//looping, to add 'change' event to each element
  once.push(1);//adding '1' to array 'i' times. Here it will look like [1,1,1];
  moo[i].addEventListener('change', function(){
    if(once[i]==0){return}//if array element equals 0 = return and don't run the function
    this.style.color = "red";
    once[i] = 0;//after triggered = making array element = 0;
    
    //just demo... remove this.
    const d = document.getElementById('demo');
    d.innerText = Number(d.innerText) + 1;
  });
}
<textarea class="moo">Change me!</textarea>
<textarea class="moo">Me too!</textarea>
<textarea class="moo">And me!</textarea>
<br><br>
Triggered times: <span id="demo">0</span>

* функция все еще работает каждый раз ... но возвращается немедленно, что лучше, чем "полный" запуск.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...