【问题标题】:digest loop shows no change in my array (and view does not refresh)摘要循环显示我的数组没有变化(并且视图不刷新)
【发布时间】:2015-01-12 10:36:50
【问题描述】:

我正在从服务调用中检索一组名称。此服务调用接受一个过滤器参数,该参数在第一次执行时最初为空(即,当我第一次显示名称表时)。

我有一个过滤器输入,用户可以在其中键入字符来过滤名称列表。此过滤器参数被传递给服务调用并更新名称列表。

在单步执行代码时,我看到我的姓名列表已更新并应用了新过滤器。我还进入了 angularjs 源代码,看到 apply \ digest 循环在名称列表更新后自动发生。但是,它不会刷新视图,因为在角度代码中,我看到数组的长度看起来没有变化(即使在我的控制器中,由于过滤器,数组更小)。

我不明白为什么 angular 看不到更新后的数组?

查看:

// My view contains the following input box where the user types in the string to filter with.
// The custom directive calls the action when focus is lost from the input (on blur).
<div class="input-group" data-ng-controller="myController">
    <input my-custom-directive action="doFilter()" ng-model="name.filter">
</div>

// Display the names using another custom directive: nameList
<div data-ng-controller="myController" name-list></div>

控制器:

myModule
.controller('myController', ['$scope', 'Names', function ($scope, Names) {

    $scope.name = { filter: '' };

    $scope.doFilter = function () {
        Names($scope.name.filter).query().$promise.then(function (data) {
                $scope.names = data;
            });
        }

        // Call doFilter to get the list of names when first enter the controller (filter is empty) 
        $scope.doFilter();
    }
]);

资源:

myModule
.factory('Names', ['$resource', '$rootScope', function ($resource, $rootScope) {
    return function (name) {
        return $resource(
            'api/getnames/:Name', {
                name: name
            });
        }
}])

最后,使用自定义 nameList 指令显示名称列表:

myModule
.directive("nameList", function () {
return {
    link: function(scope, element, attrs) {

        var update = function() {
            var data = scope["names"];
        }

        var watcherFn = function(watchScope) {
            return watchScope.$eval(data, data[i]);
        }

        scope.$watchCollection('names', function (newValue, oldValue) {
            update();
        });
    },
    template:
    "<table class='table table-hover'>"
        + "<tbody>"
        + "<tr ng-repeat='n in names'>"
        + "        <td>{{n.first}}</td>"
        + "        <td>{{n.last}}</td>"
        + "    </tr>"
        + "</tbody>"
        + "</table>"
    }    
})

当首次输入myController 时,我看到了预期的完整名称列表,因为在首次输入控制器时调用了doFilter,但过滤器为空。

当我在过滤器输入中输入一些字符时,我看到 $scope.names 已在 doFilter 中更新,名称列表更小。

但是视图没有更新。如果我进入角度源代码,特别是在 $digest 函数内部:

if (watch) {
  if ((value = watch.get(current)) !== (last = watch.last) &&
     !(watch.eq
       ? equals(value, last)
       : (typeof value === 'number' && typeof last === 'number'
       && isNaN(value) && isNaN(last)))) {

我看到当前值始终与最后一个值相同(当我点击我的特定手表集合时),当前数组仍然是原始的大型名称数组(而在调用堆栈中更高的名称由于过滤器,数组已更新为更小的数组)。

为什么 Angular 看不到我的新大小的数组?

请注意,我还尝试将 $watchCollection 更新为仅使用 $watch(最后一个参数为 true),结果相同,并且我还尝试将 $scopes.names = data 再次包装在 $scope.$apply() 中没有变化。

【问题讨论】:

  • 那里有两个 myController。每个都有自己的范围,而不是一个共同的范围。
  • 哦,我明白了 - 在视图中!好的,是的,你是对的!!请回复为答案,以便我接受!
  • 过滤和动作指令在一个控制器下,视图在另一个控制器下。

标签: javascript arrays angularjs angularjs-scope watch


【解决方案1】:

那里有两个 myController。每个都有自己的范围,而不是通用范围。

通常的解决方案是为可以注入控制器的公共数据使用服务。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-26
    • 1970-01-01
    • 1970-01-01
    • 2015-09-09
    • 2021-05-16
    • 2014-10-30
    • 2021-02-25
    相关资源
    最近更新 更多