【发布时间】: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