0

[2015 年 7 月 23 日更新] 我想创建一个按钮列表,每个markerctrl.getMarkers(). 让我们假设标记类似于 marker: {'title':' '}.

使用经典的ng-repeat,我有以下

<div ng-repeat="marker in ctrl.getMarkers()" >
        <button class="btn btn-default" 
                ng-click = "doSomething(marker)"
                ng-style="ctrl.isRed() ? {color:red} : {color:black}">
              <b> {{::marker.title}}</b>                                                                                                                            
        </button>   
</div>

我有大约 100 个按钮要显示,但更新速度并不快。所以我想试试ng-react库。不幸的是,我还不太了解如何使用它。

到目前为止,我写了这个:

HTML

<poi-list list="ctrl.getMarkers()" />

JS

 /** @jsx React.DOM */
 .value( "PoiList", React.createClass( {

  propTypes : {

    list: React.PropTypes.object.isRequired
  },

  getDefaultProps: function() {
    return { list: [] };
  },

  render: function() 
   {
    var markers = this.props.list.map( function( marker, i ) 
        {
         return React.DOM.button({className:'btn btn-default'
                                  /*ng-click? ng-class?*/
                                 }, marker.title) ;
        } );
    return React.DOM.div(null, markers);
    }
}))

.directive( 'poiList', function( reactDirective ) {
  return reactDirective( 'PoiList' );
} );

我如何将ng-click,ng-class等与 React DOM 元素一起使用?

这是JSFiddle

[更新 2]

我找到了解决方案,并在下面回答了我自己的问题。但是,我仍然遇到一个减慢反应速度的问题:“不推荐尝试访问非节点对象上的属性 'nodeType'”。请在下面查看我的答案以获取有关该错误的更多信息。谢谢

4

1 回答 1

1

我想出了如何(几乎)解决我的问题。我将控制器作为反应元素的属性传递,所以我可以调用它的函数。像这样:

HTML

<poi-list list="ctrl.getMarkers()" ctrl="ctrl"/>

JS

 .value( "PoiList", React.createClass( {

  propTypes : {

    list: React.PropTypes.object.isRequired,
    ctrl: React.PropTypes.object.isRequired
  },

  render: function() 
   {
    var ctrl = this.props.ctrl; // directive's Controller

    var markers = this.props.list.map( function( marker, i ) 
        {
         return React.DOM.button(  {
                                    className:'btn btn-default',
                                    onClick: function(){ctrl.doSomething(marker);},
                                    onMouseOver: function(){ctrl.doSomethingElse(marker);},                               
                                   }, marker.title
                                 ) ; 
        } );
    return React.DOM.div(null, markers);
    }


}))

.directive( 'poiList', function( reactDirective ) {
  return reactDirective( 'PoiList' );
} );

有用!!JSFiddle

[更新 1]

无论如何....在我的实际应用程序中非常慢......比ng-repeat慢得多。我不知道为什么。查看控制台,我有一堆"Deprecated attempt to access property 'nodeType' on a non-Node object"来自 angular.js:328 的错误,我想这是性能缓慢的原因。我不知道有什么问题,而且我在 JSFiddle 中没有这个错误......有什么帮助吗?

这是引发错误的 Angular 代码:

    function forEach(obj, iterator, context) {
      var key, length;
      if (obj) {
        if (isFunction(obj)) {
          for (key in obj) {
            // Need to check if hasOwnProperty exists,
            // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function
            if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {
              iterator.call(context, obj[key], key, obj);
            }
          }
/*---->*/  } else if (isArray(obj) || isArrayLike(obj)) {// <---ERR
          var isPrimitive = typeof obj !== 'object';
          for (key = 0, length = obj.length; key < length; key++) {
            if (isPrimitive || key in obj) {
              iterator.call(context, obj[key], key, obj);
            }
          }
        } else if (obj.forEach && obj.forEach !== forEach) {
            obj.forEach(iterator, context, obj);
        } else {
          for (key in obj) {
            if (obj.hasOwnProperty(key)) {
              iterator.call(context, obj[key], key, obj);
            }
          }
        }
      }
      return obj;
    }

[更新 2]

我发现问题在于传递给 React Element 的复杂对象数组。React 无法在新旧对象之间进行比较,从而导致缓慢和错误。这是对这个问题的解释和解决方案。

于 2015-07-23T16:32:10.097 回答