gpt4 book ai didi

javascript - AngularJS : $watch vs. $observe when newValue === oldValue

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:43:08 27 4
gpt4 key购买 nike

如果这已经在某处解释或讨论过,我很抱歉,但我找不到任何地方讨论过这个确切的问题。

所以我有一个带有一个数据绑定(bind) 'myvar' 的 Angular Directive(指令)(= 或 @ 没有区别)。来自数据绑定(bind)的值在指令中使用:scope.myvarStr = scope.myvar + 'somestring'。然后我在模板中绑定(bind) myvarStr。

因为 scope.myvarStr 必须在 scope.myvar 更改时进行修改,所以我使用 $watch('myvar', function(...)) 来监视值并在需要时更新 scope.myVarStr。在 watch 函数中我放了经典的 if (newValue === oldValue) return;

问题在 $watch 第一次触发并且两个值相等时出现;然后 View 没有更新。我可以很容易地从链接函数第一行的 console.log(scope.myvar) 中看到 scope.myvar 是未定义的(或“依赖于绑定(bind)类型”),并且该值已更改为其他值我在 $watch 中做了一个 console.log。

我用谷歌搜索了一个小时左右,找到了这个:https://github.com/angular/angular.js/issues/11565然而,这个问题没有在其他任何地方讨论过,所以我在谷歌上搜索了更多并遇到了 $observe AngularJS : Difference between the $observe and $watch methods

当我从 $watch 更改为 $observe 时,我所有的问题都消失了,我仍然可以使用 if(newValue === oldValue) return;。

(function(directives) {
'use strict';

directives.directive('someDir', [function() {
return {
restrict: 'E',
scope: {
myvar: '=' //or @ didn't matter at the time...
},
template: '<p>{{myvarStr}}</p>',
link: function(scope, el, attrs) {

function toString() {
if (scope.myvar < 1000) {
scope.myvarStr = scope.myvar;
} else {
scope.myvarStr = scope.myvar/1000 + 'k';
}
}
toString();

scope.$watch('myvar', function(newValue, oldValue) {
console.log("changed", newValue, oldValue)
if (newValue == oldValue) return;
toString();
},true);

// When changing to $observe it works :)
//attrs.$observe('myvar', function(newValue, oldValue) {
// console.log("changed", newValue, oldValue)
// if (newValue == oldValue) return;
// toString();
//},true);

}
};
}]);
}(angular.module('myApp.directives')));

建议:据我所知,$watch 会出现此问题,因为范围值永远不会更改。指令需要一段时间才能获取值,直到那时绑定(bind)只是一个空字符串或其他东西,当检测到该值时 $watch 触发但实际范围值没有改变(或如第一个链接中所述; 当值“出现”在指令中时,第一个 watch 触发。

最佳答案

我不太明白你的建议/解释,但我觉得事情比你说的要简单得多。

您不需要 newValue === oldValue 测试,因为您的 watch-action 是幂等且廉价的。但即使你这样做,也只意味着你需要自己初始化值(例如,通过手动调用 toString()),你似乎正在这样做,因此你的指令应该按预期工作。 (事实上​​,我无法用您的代码重现您提到的问题。)

无论如何,这是一个(更简单的)working version :

.directive('test', function testDirective() {
return {
restrict: 'E',
template: '<p>{{ strVal }}</p>',
scope: {
val: '='
},
link: function testPostLink(scope) {
scope.$watch('val', function prettify(newVal) {
scope.strVal = (!newVal || (newVal < 1000)) ?
newVal :
(newVal / 1000) + 'K';
});
}
};
})

顺便说一句,因为你只是想“格式化”一些显示值,所以看起来 filter$watch 更合适(并且清除 imo) >(参见 above demo):

.filter('prettyNum', prettyNumFilter)
.directive('test', testDirective)

function prettyNumFilter() {
return function prettyNum(input) {
return (!input || (input < 1000)) ? input : (input / 1000) + 'K';
};
}

function testDirective() {
return {
template: '<p>{{ val | prettyNum }}</p>',
scope: {val: '='}
};
}

关于javascript - AngularJS : $watch vs. $observe when newValue === oldValue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30356803/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com