[UPDATE 23 июля 2015] Я хочу создать список кнопок, по одному для каждого marker
в ctrl.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 на объекте, отличном от Node". Пожалуйста, посмотрите мой ответ ниже для получения дополнительной информации об ошибке. спасибо
Я выяснил, как (почти) решить мою проблему. Я передаю контроллер как атрибут элемента реакции, поэтому я могу вызвать его функции. Как это:
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 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"
отличном от "Deprecated attempt to access property 'nodeType' on a non-Node object"
от angular.js: 328, и я думаю, что это причина медленной производительности. Я не знаю, в чем проблема, и у меня нет этой ошибки в JSFiddle... любая помощь?
Это часть углового кода, которая вызывает ошибку:
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. Невозможно для React сделать сравнение старого и нового объекта, что приводит к медленности и ошибкам. Это объяснение этой проблемы и решения.