圆形对象,非法 isArrayLike() 调用和无限 $digest 循环创建 <div> with ngReact
circular objects, illegal isArrayLike() invocation and Infinite $digest loop creating a <div> with ngReact
[9 月 24 日更新]
当我修改我的 $watched 对象数组时,我正在尝试使用 ngReact 而不是 ngRepeat 来提高性能。
对于控制器中包含的每个对象(地图标记),我想创建一个 <button>
,其中 marker.title
作为文本。为此,我创建了一个 $watches 标记数组的 React 组件。这样的 a 包含一个列表,每个标记一个。我认为只有当我修改标记列表,然后修改按钮列表时,组件才会导致 changed。然而事实并非如此。
[TypeError]: Illegal invocation
at isArrayLike (angular.js:274)
at forEach (angular.js:328)
at copy (angular.js:886)
[Error]: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: []
http://errors.angularjs.org/1.4.0-rc.0/$rootScope/infdig?p0=10&p1=%5B%5D
at REGEX_STRING_REGEXP (angular.js:68)
at Scope.parent.$get.Scope.$digest (angular.js:15340)
at Scope.parent.$get.Scope.$apply (angular.js:15570)
at (index):95
似乎 React 组件创建的 <button>
列表结果总是不同的,即使是由相同的对象创建的。
现在是奇怪的部分。实际上,我使用 Json 对象向地图添加标记。当我添加一个 Json 对象时,地图会创建一个 Marker
对象,而不是 jsonable 因为它具有循环结构。我将此 Marker
对象添加到我的 $watched 数组中,以创建相对对象 <button>
... 也许这就是 illegal isArrayLike()
错误的原因?
这是我的 React 组件(在我的 post 末尾,有 JSfiddle link)
HTML
<!-- m_list is an attribute of $rootScope -->
<poi-list list="m_list" />
JS
.value( "PoiList", React.createClass( {
propTypes : {
list: React.PropTypes.object.isRequired
},
render: function()
{
var markers = this.props.list.map( function( marker, i )
{//for each marker, create a button
return React.DOM.button( {
className:'btn btn-default'
}, marker.title
) ;
} );
return React.DOM.div({}, markers);
}
}))
.directive( 'poiList', function( reactDirective ) {
return reactDirective( 'PoiList' );
} );
this is a JSFiddle 我的问题。简要说明:
- $rootScope 中有 2 个数组。 temp_list 用于暂时将所有标记一个一个地推送。 m_list 被 React 组件 $watched。
- 有一个 MapBox 指令及其控制器。对于添加到地图的每个标记,它将被推入 temp_list.
- 一旦所有标记都已加载并且 temp_list 完成,这将被克隆到 m_list,因此可以更新反应组件。
谢谢
我找到了解决办法!这个问题不知何故与地图的使用有关。在观察数组中,我没有添加 Json 标记,但我添加了由 MapBox 创建的对象标记。
map.featureLayer.setGeoJSON(json_markers_list); // I pass an array of Json markers
map.featureLayer.on('layeradd', function(e)
{
var marker = e.layer; // marker is anymore a json obj
ctrl.pushMarker(marker); // marker now has a cyclic structure
});
MapBox创建的对象标记,具有循环结构。出于这个原因,React 无法知道旧的 $watched 数组自上次检查以来是否发生了变化,因为当循环结构存在时它无法执行 isArrayLike()
。所以它会引发错误(在任何浏览器中都不同)并认为数组总是在变化,生成 $digest 无限迭代。
我的解决方案是使用一个数组和一张地图。该数组是 $watched,仅包含我需要在按钮中显示的信息
{'title': 'marker title', 'id':00001}
地图包含真实的标记对象
{'00001' : {markerObj}}
这是有效的 JSFiddle!单击一个按钮,标记对象将被选中。
这个问题和解决方案也在official ng-react project
的论坛上发帖
[9 月 24 日更新]
当我修改我的 $watched 对象数组时,我正在尝试使用 ngReact 而不是 ngRepeat 来提高性能。
对于控制器中包含的每个对象(地图标记),我想创建一个 <button>
,其中 marker.title
作为文本。为此,我创建了一个 $watches 标记数组的 React 组件。这样的 a 包含一个列表,每个标记一个。我认为只有当我修改标记列表,然后修改按钮列表时,组件才会导致 changed。然而事实并非如此。
[TypeError]: Illegal invocation
at isArrayLike (angular.js:274)
at forEach (angular.js:328)
at copy (angular.js:886)
[Error]: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: []
http://errors.angularjs.org/1.4.0-rc.0/$rootScope/infdig?p0=10&p1=%5B%5D
at REGEX_STRING_REGEXP (angular.js:68)
at Scope.parent.$get.Scope.$digest (angular.js:15340)
at Scope.parent.$get.Scope.$apply (angular.js:15570)
at (index):95
似乎 React 组件创建的 <button>
列表结果总是不同的,即使是由相同的对象创建的。
现在是奇怪的部分。实际上,我使用 Json 对象向地图添加标记。当我添加一个 Json 对象时,地图会创建一个 Marker
对象,而不是 jsonable 因为它具有循环结构。我将此 Marker
对象添加到我的 $watched 数组中,以创建相对对象 <button>
... 也许这就是 illegal isArrayLike()
错误的原因?
这是我的 React 组件(在我的 post 末尾,有 JSfiddle link)
HTML
<!-- m_list is an attribute of $rootScope -->
<poi-list list="m_list" />
JS
.value( "PoiList", React.createClass( {
propTypes : {
list: React.PropTypes.object.isRequired
},
render: function()
{
var markers = this.props.list.map( function( marker, i )
{//for each marker, create a button
return React.DOM.button( {
className:'btn btn-default'
}, marker.title
) ;
} );
return React.DOM.div({}, markers);
}
}))
.directive( 'poiList', function( reactDirective ) {
return reactDirective( 'PoiList' );
} );
this is a JSFiddle 我的问题。简要说明:
- $rootScope 中有 2 个数组。 temp_list 用于暂时将所有标记一个一个地推送。 m_list 被 React 组件 $watched。
- 有一个 MapBox 指令及其控制器。对于添加到地图的每个标记,它将被推入 temp_list.
- 一旦所有标记都已加载并且 temp_list 完成,这将被克隆到 m_list,因此可以更新反应组件。
谢谢
我找到了解决办法!这个问题不知何故与地图的使用有关。在观察数组中,我没有添加 Json 标记,但我添加了由 MapBox 创建的对象标记。
map.featureLayer.setGeoJSON(json_markers_list); // I pass an array of Json markers
map.featureLayer.on('layeradd', function(e)
{
var marker = e.layer; // marker is anymore a json obj
ctrl.pushMarker(marker); // marker now has a cyclic structure
});
MapBox创建的对象标记,具有循环结构。出于这个原因,React 无法知道旧的 $watched 数组自上次检查以来是否发生了变化,因为当循环结构存在时它无法执行 isArrayLike()
。所以它会引发错误(在任何浏览器中都不同)并认为数组总是在变化,生成 $digest 无限迭代。
我的解决方案是使用一个数组和一张地图。该数组是 $watched,仅包含我需要在按钮中显示的信息
{'title': 'marker title', 'id':00001}
地图包含真实的标记对象
{'00001' : {markerObj}}
这是有效的 JSFiddle!单击一个按钮,标记对象将被选中。
这个问题和解决方案也在official ng-react project
的论坛上发帖