$watch 只触发一次
Posted
技术标签:
【中文标题】$watch 只触发一次【英文标题】:$watch only triggering once 【发布时间】:2015-09-07 05:14:51 【问题描述】:我正在为 AngularJS 使用智能表 (http://lorenzofox3.github.io/smart-table-website/),并且我创建了一个名为 isReset 的标志,它将触发表重新加载。发生这种情况是因为我有一个监视标志的指令,并且在设置 isReset 时会运行刷新,并且在刷新完成后,它将再次关闭标志。
我的问题是,当我设置标志时,它第一次运行,但在监视标志的行为之后,它似乎永远不会设置回 false。我尝试手动将标志设置为 false,但下一次 $watch 甚至没有触发。我的代码如下,如果您能帮助我阐明这个问题,那就太好了。最奇怪的是,我在另一个地方以完全相同的方式使用它,而且它按预期工作。
JS
$scope.resetFilter = function()
$scope.timestampFilter = "";
$scope.levelFilter = "";
;
$scope.getAPIServerLogs = function (tableState)
$scope.isLoading = true;
ServerLog.get(
"serverType": "API",
"timestampFilter": $scope.timestampFilter,
"levelFilter": $scope.levelFilter,
"offset": tableState.pagination.start,
"limit": tableState.pagination.number,
"sortField": tableState.sort.predicate,
"order": tableState.sort.reverse ? "desc" : "asc"
, function (response)
$scope.isLoading = false;
$scope.serverlogs = response.data;
$scope.displayedserverlog = [].concat($scope.serverlogs);
tableState.pagination.numberOfPages = response.pages;
);
;
指令
directives.directive('stReset', function ()
return
require: '^stTable',
replace: false,
scope: stReset: "=stReset",
link: function (scope, element, attr, ctrl)
scope.$watch("stReset", function ()
if (scope.stReset)
// reset scope value
var tableState = ctrl.tableState();
tableState.pagination.start = 0;
tableState.sort.prediate = ;
tableState.search = ;
ctrl.pipe();
scope.stReset = false;
, true);
;
<table st-table="displayedserverlog" st-safe-src="serverlogs" st-pipe="getAPIServerLogs"
class="table table-striped table-hover logtable">
<thead st-reset="isReset">
<tr>
<th st-sort-default="reverse" st-sort="timestamp" >Timestamp</th>
<th st-sort="logger" >logger</th>
<th st-sort="level" >Level</th>
<th st-sort="thread" >Thread</th>
<th st-sort="message" >Message</th>
</tr>
</thead>
<tbody ng-repeat="serverlog in serverlogs">
<tr ng-click="click(serverlog)" ng-class="'tr-active':serverlog.isClicked, 'pointer danger':serverlog.exception">
<td>serverlog.timestamp | date: 'yyyy-MMM-dd hh:mm:ss'</td>
<td>serverlog.logger</td>
<td>serverlog.level</td>
<td>serverlog.thread</td>
<td>serverlog.message</td>
</tr>
<tr ng-show="serverlog.isClicked">
<td colspan="6">
<div class="row">
<div class="col-md-12">
<div>serverlog.exception</div>
<pre><div ng-repeat="trace in serverlog.stacktrace track by $index" class="stacktrace">trace
</div></pre>
</div>
</div>
</td>
</tr>
</tbody>
<tfoot ng-hide="isLoading">
<tr>
<td colspan="10" class="text-center">
<div st-pagination="" st-items-by-page="50"></div>
</td>
</tr>
</tfoot>
【问题讨论】:
ServerLog.get
代码包含什么?是 jQuery ajax 吗? 或者你只有控制台错误吗?
$watch 函数。需要两个参数,newVal 和 oldVal。 docs.angularjs.org/api/ng/type/$rootScope.Scope。另外,为什么要检查对象相等性?
@pankajparkar 仅控制台错误。好吧,甚至没有错误,它只是不符合我的预期。
remove scope: stReset: "=stReset",
您正在从父范围读取/观看值的副本,或者您可以尝试使用 @ 而不是 =
【参考方案1】:
试试这个。
var watcher = $scope.$watch('someScope', function(newValue, oldValue)
if(newValue === 'yourValue')
watcher(); // stop this watch
);
【讨论】:
【参考方案2】:我发现了一个解决方案。仍然不确定它为什么有效,但我添加了
scope.$parent.$parent.isReset = false;
到指令的末尾,它按照预期的方式工作。但是,替换现有的
scope.stReset = false;
打破了我正在使用该指令的另一个地方。现在,我将两者都做。将来当我在 AngularJS 上变得更聪明时,我会重新审视这个问题。我希望这对将来的某人有所帮助,这样他们就不会像我一样浪费 3 天的时间来弄清楚它。
【讨论】:
【参考方案3】:这个 plunker 模拟你的问题:http://plnkr.co/edit/c8crhe9ZR44GQBJ2sqm6?p=preview(看看控制台)
scope.$watch("flag", function(neww, old)
count ++;
console.log("inWatch " + count + ": " + neww + ', ' + old);
if (scope.flag === true)
scope.flag = false;
);
在 $watch 中将标志设置为 false 基本上意味着它将始终为 false(因为:您修改了值 --> $watch 运行 --> 在函数的末尾将值设置为 false --> 值是假的)
【讨论】:
你是对的。有一行重要的代码我不小心遗漏了,它是一个将“isReset”设置为 true 的按钮。这应该重置表,因为它应该通过 "st-reset="isReset",=> 触发 $watch => pipe() 重新加载 table => isReset 再次为 false 绑定。我的问题是 isReset 没有设置在这个代码的实现中由于某种原因为 false,即使在不同的页面上它也能像我们预期的那样完美地工作(并且你在 plunker 中很好地布置了) 所以,当你说它在另一个页面上工作时......你是在两个页面上使用相同的指令(st-reset)(并得到不同的结果),还是你有类似的实现和它按预期工作吗? 据我所见(与 st-reset 交互的代码行),它们是相同的(使用 st-reset 触发 st-table 上的刷新)。不同之处在于,对于这个块,$watch 没有将 isReset 设置为 false,并且似乎不会再次触发,即使在块之外手动设置为 false 也是如此。以上是关于$watch 只触发一次的主要内容,如果未能解决你的问题,请参考以下文章