Выполнить $ watch или $ watch once

78
13

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

Есть ли способ выполнить только тот или иной, с соблюдением приоритета над часами.

var myFunction = function{
//my code
}

scope.$parent.$watch('Parent.Var', myFunction);
attrs.$observe('myAttr', myFunction);

В настоящее время я использую тайм-аут 100 мс, однако в некоторых случаях он все еще запускает оба. Я чувствую, что механизм немного сложный, поскольку он зависит от того, насколько хорошо реагируют браузеры.

Уточнение моего вопроса немного больше: моя область обновляет Parent.var, который затем запускает часы. Во время одного и того же цикла дайджеста он обновит myAttr позже, после чего начнется наблюдение.

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

Заранее спасибо!

спросил(а) 2021-01-25T15:49:13+03:00 5 месяцев назад
1
Решение
109

Вы можете просто использовать переменную блокировки.

var myFunctionLock = false;

var myFunction = function(){
if (myFunctionLock) return;
myFunctionLock = true

//my code

myFunctionLock = false
}

scope.$parent.$watch('Parent.Var', myFunction);
attrs.$observe('myAttr', myFunction);

Если есть вероятность, что функция вернется до достижения цели, вы, вероятно, захотите также добавить какой-то временной лимит в верхнюю часть, например

    ...
if (myFunctionLock) return;
myFunctionLock = true
var t = setTimeout(function(){ myFunctionLock = false; }, 500);
...
myFunctionLock = false
clearTimeout(t);

так что функция снова станет пригодной для использования.

Чтобы достичь своего рода "приоритетного исполнения" для $ observ, вы могли бы заставить другие вызовы просто немного подождать, чтобы дать $ наблюдать за изменением огня и пропустить его к голове.

var myFunctionWait = function(){
// wait a bit, to give $observe a chance to fire.
setTimeout(function(){ myFunction(); }, 100);
}

scope.$parent.$watch('Parent.Var', myFunctionWait);
attrs.$observe('myAttr', myFunction);

ответил(а) 2021-01-25T15:49:13+03:00 5 месяцев назад
44

Благодаря обоим ответам!

Я смешал оба и достиг решения.

var myFunctionWait = function(){
// wait a bit, to give $observe a chance to fire.
setTimeout(function(){ myFunction(); }, 100);
}

var myAttrFunction = function(){
unbindWatch();
myFunction();
}

var unbindWatch = scope.$parent.$watch('Parent.Var', myFunctionWait );
attrs.$observe('myAttr', myAttrFunction);

К сожалению, у меня еще нет репутации, чтобы повышать :(

ответил(а) 2021-01-25T15:49:13+03:00 5 месяцев назад
45

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

Способ развязать $ watch:

var unbindWatch = scope.$parent.$watch('Parent.Var', myFunction);

function myFunction() {
// @TODO add your code here which need to be executed
unbindWatch();
}

Способ развязать $ наблюдать:

var unbindObserve = attrs.$observe('myAttr', myFunction);

function myFunction() {
// @TODO add your code here which need to be executed
unbindObserve();
}

Таким образом, приведенный выше код обеспечит выполнение только один раз.

ответил(а) 2021-01-25T15:49:13+03:00 5 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема