【问题标题】:AngularJS watch not workingAngularJS手表不工作
【发布时间】:2014-12-10 20:59:11
【问题描述】:

手表不工作。 我ng-包括以下内容:

<form class="search">
    <div class="searchbar">
        <input type="search" value="" data-ng-model="searchKeyword" placeholder="zoeken">
        <button type="submit"><i class="glyphicon glyphicon-search"></i></button>
    </div>
</form>

像这样:

<div ng-include src="filterPath" onload="initiateSearch()"></div>

onload 函数是这样做的:

(function(){
    var appController = angular.module('ListerAppController', []);

    appController.controller('ListerCtrl', ['$scope', '$rootScope', '$http', '$filter', '$timeout', '$sharedFactories', 'History', '$location',
        function($scope, $rootScope, $http, $filter, $timeout, $sharedFactories, History, $location) {
            $scope.initiateSearch = function () {
            // This is what you will bind the filter to
                $scope.filterText = '';

                // Instantiate these variables outside the watch
                var tempFilterText = '',
                    filterTextTimeout;

                $scope.$watch('searchKeyword', function (val) {
                    if (filterTextTimeout) $timeout.cancel(filterTextTimeout);

                    tempFilterText = val;

                    filterTextTimeout = $timeout(function() {
                        $scope.filterText = tempFilterText;
                        $scope.pageCount = function() {
                            return Math.ceil( $scope.itemsfiltered.length / $scope.itemsPerPage );
                    };
                }, 350); // delay 250 ms
            });
        };
    }]);
})();

一切似乎都很好,但是...当我开始输入名为 searchKeyword 的输入元素时,searchKeyword 上的 $watch 永远不会触发该功能。

【问题讨论】:

  • watch放在控制器里面而不是initiateSearch里面
  • onload 应该在 &lt;div&gt; 上做什么?特别是因为它试图调用角度范围内的方法。在控制器中调用你的方法
  • 为什么要注入$rootScope?您是否在某处使用它,但您已从代码示例中删除了该部分?我通常会尽量避免使用 $rootScope ,除非别无选择,但通常总会有更好的解决方案。这个 IMO 不是您问题的根源,只是好奇。
  • 当模板的 ng-include 完成加载时,onload 正在调用控制器内部的方法。当它准备好时,带有 ng-model="searchKeyword" 的元素就会存在。然后我想应用 $scope.$watch('searchKeyword', function(){})。问题是它在 $scope.initiateSearch = function () {} 内。将手表放在范围功能之外使其再次工作

标签: angularjs watch


【解决方案1】:

您是否尝试过添加true,如下所示?

$scope.$watch('searchKeyword', function (val) {
 /* your logic here */                    
}, true);

如果您对true 是什么感到好奇,这里是来自the docs 的函数签名:

$watch(watchExpression, listener, [objectEquality]);

当 objectEquality == true 时,watchExpression 的不等式由 angular.equals 函数确定。为了保存对象的值以供以后比较,使用了 angular.copy 函数。因此,这意味着观看复杂的对象会对内存和性能产生不利影响。

显然,重要的是它以不同的方式检查旧值和新值的相等性。如果(如果我错了,请纠正我)您正在观看的值是数组而不是字符串,我可以看到这是必要的。

【讨论】:

  • 啊……这对我有用。试图捕捉对象的变化,但观察不够深入。干杯。
  • 任何嵌套的对象都需要这个。很好的答案。
  • 如果你只需要一个对象或数组的浅层监视而不是深层监视,请使用$watchCollection 而不是docs.angularjs.org/api/ng/type/$rootScope.Scope
【解决方案2】:

手表必须是对象的属性,而不是对象本身,请参阅此处的示例https://docs.angularjs.org/api/ng/type/$rootScope.Scope 了解如何添加手表,以及此处的模型使用https://docs.angularjs.org/api/ng/directive/input。 你可以试试这个(我没有测试过)

data-ng-model="search.keyword"

在你的控制器中:

$scope.search = {}

...

$scope.$watch('search.keyword', ... 

【讨论】:

  • 如果我在 ng-repat 中使用模型会怎样?例如,对于以下情况,$watch 不起作用:&lt;md-checkbox ng-repeat="project in tree" aria-label="{{tree.name}}" ng-model="filter.projects[project.id]" ng-init="true"&gt;{{project.name}}&lt;/md-checkbox&gt;
【解决方案3】:

只是添加到可能的解决方案列表中:

使用表单时:

使用 ng-pattern 将抑制对 $watch 的调用,除非输入被 ng-pattern 验证。

所以以防万一,如果有人在使用 ng-pattern,请在删除 ng-pattern 后尝试 $watch。

更多阅读:

Angular.js - ng-change not firing when ng-pattern is $invalid

【讨论】:

    【解决方案4】:

    最简单的方法是将 true 作为 $watch 的最后一个参数传递。

    更多阅读:

    https://github.com/mbenford/ngTagsInput/issues/174

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多