循环对象,非法的isArrayLike()调用和无限$digest循环创建<div>与ngReact一起


ngReact。

[9月24日更新]

我试图使用ngReact而不是ngRepeat来提高性能,当我修改我的$watched对象数组。

对于控制器中包含的每个对象(一个地图标记),我想创建一个<button>,其中marker.title为文本。为此,我创建了一个React组件来$监视一组标记。这样的目录包含一个列表,每个标记对应一个。我假定组件只有在修改标记列表和按钮列表时才会导致改变。然而,事实并非如此。

[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组件(在我的文章末尾,有JSfiddle链接)

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' );
} );

这是我的问题的JSFiddle。简要说明:

  • $rootScope中有两个数组。Temp_list用于一个接一个地临时推入所有标记。m_list由react组件$监视。
  • 有一个MapBox指令和它的控制器。对于添加到地图中的每个标记,它将被推送到temp_list中。
  • 一旦所有的标记都被加载并且temp_list完成,它就被克隆到m_list,这样react组件就可以被更新了。

谢谢

我找到解决办法了!这个问题在某种程度上与地图的使用有关。在观察数组中,我没有添加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 !点击一个按钮,标记对象将被选中。

这个问题和解决方案也是在官方ng-react项目论坛上的海报

相关内容

最新更新