Angularjs 多次角度定向射击
我是AngularJS的新手,有一个问题我希望有人能给我指出正确的方向来解决。我已经创建了一个名为Angularjs 多次角度定向射击,angularjs,Angularjs,我是AngularJS的新手,有一个问题我希望有人能给我指出正确的方向来解决。我已经创建了一个名为sizeWatcher的指令,该指令作为一个属性放入HTML中,它基本上只是获取它所放置元素的高度,并将该高度回显到名为style的范围变量中,我通过使用ng style=“style”将该高度设置到另一个元素上 我发现每当我打开手风琴时,$watch都会按指令启动,但会启动多次。我在我的$watch中有一个控制台。log,我看到了3个日志条目,前2个是相同的(猜测这发生在手风琴打开前的单击上,然后
sizeWatcher
的指令,该指令作为一个属性放入HTML中,它基本上只是获取它所放置元素的高度,并将该高度回显到名为style
的范围变量中,我通过使用ng style=“style”
将该高度设置到另一个元素上
我发现每当我打开手风琴时,$watch
都会按指令启动,但会启动多次。我在我的$watch
中有一个控制台。log
,我看到了3个日志条目,前2个是相同的(猜测这发生在手风琴打开前的单击上,然后手风琴打开,第3个日志条目是打开手风琴后的最终高度)。主要问题是,style
变量仅在手风琴展开之前设置为较小的高度,即使日志记录的是指令最后一次命中时的较大高度——我如何忽略第一个$watch
事件触发,而仅在指令的最后一次和最后一次运行时采取相应的行动指令?如能对此有所了解,将不胜感激。相关代码附于下文:
模板:
<div class="content-wrap" id="height-block" ng-style="style">
<!-- Other HTML etc... -->
<uib-accordion size-watcher close-others="oneAtATime">
<!-- Accordion Directive HTML.. -->
</uib-accordion>
</div>
.directive("sizeWatcher", function () { //add size-watcher attribute to element on the page to have it echo its' height to the {{style}} scope
function link(scope, element, attrs) {
scope.$watch(function () { //watch element for changes
var height = element[0].offsetHeight;
console.log(height);
if (height > 150) {
scope.style = {
height: height + 'px'
};
}
});
}
return {
restrict: "AE", //attribute & element declarations
link: link
};
})
我怎么能忽略第一次$watch事件触发而只采取行动
因此,在指令的最后一次和最后一次运行时
当新值或旧值未定义且彼此不相等时,可以忽略观察者:
$scope.$watch(function () {
return element.height(); // or something else
},
function (newVal, oldVal) {
if (newVal !== undefined && oldVal !== undefined && newVal !== oldVal) {
// your stuff
if (newVal > 150) {
scope.style = {
height: newVal + 'px'
};
}
}
});
不管怎样,你可以根据自己的需要使用if语句
仅供参考,为了提高性能,
$watch
返回取消回调,以便您可以随时停止watcher:
var cancelWatch = $scope.$watch(function () {
return element.height();
},
function (newVal, oldVal) {
if (<some condition>) {
cancelWatch();
}
});
var cancelWatch=$scope.$watch(函数(){
返回元素。高度();
},
函数(newVal,oldVal){
如果(){
取消手表();
}
});
显然,要回答这个问题,需要一个指向;)的链接
它声明如下:
在向作用域注册观察程序后,异步调用侦听器
fn(通过$evalAsync
)初始化观察程序。在极少数情况下,这是不可取的,因为在watchExpression
的结果没有更改时调用侦听器。要在侦听器中检测此场景
fn,可以比较newVal
和oldVal
。如果这两个值相同(==
),则由于初始化而调用了侦听器
这可能是你第一次打电话的原因
我猜发生第二个调用是因为手风琴在初始化(带有标题/或标签或任何东西)后会重新播放,这会触发$digest
,从而触发高度上的$watch
表达式
最后,当你打开手风琴时,第三次呼叫发生,高度实际上发生了变化
要解决这个问题,你可以比较被关注表达式的newValue和oldValue,就像Maxim Shoustin在回答中所说的那样。下面是一个示例(同样取自角度文档)
但是,如果您确实想要更改元素的样式,您可能需要查看一下,而不是手动注册任何观察者发生这种情况是因为您没有正确使用$watch
- $watch的第一个参数是要监视的变量(可以是回调)
- $watch的第二个参数是一个回调,它对更改执行所需的操作
scope.$watch(
function () {
return element[0].offsetHeight;
},
function () { //watch element for changes
var height = element[0].offsetHeight;
console.log(height);
if (height > 150) {
scope.style = {
height: height + 'px'
};
}
}
)
请注意第一个函数,因此每当它返回的值发生更改时,第二个回调将执行
希望这对你有帮助
scope.$watch(
function () {
return element[0].offsetHeight;
},
function () { //watch element for changes
var height = element[0].offsetHeight;
console.log(height);
if (height > 150) {
scope.style = {
height: height + 'px'
};
}
}
)