如何使 ngReact 与 ng 指令(ngClick、ngStyle 等)一起工作
how to make ngReact work with ng-directives (ngClick, ngStyle, etc.)
[2015 年 7 月 23 日更新]
我想创建一个按钮列表,每个按钮对应 ctrl.getMarkers()
中的 marker
。让我们假设一个标记是这样的
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]
我找到了解决方案,并在下面回答了我自己的问题。但是我仍然有一个问题,反应变慢了:"Deprecated attempt to access property 'nodeType' on a non-Node object"。请查看下面我的回答以获取有关该错误的更多信息。谢谢
我想出了如何(几乎)解决我的问题。我将控制器作为反应元素的属性传递,因此我可以调用它的功能。像这样:
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慢得多。我不知道为什么。查看控制台,我从 angular.js:328 收到一堆错误 "Deprecated attempt to access property 'nodeType' on a non-Node object"
,我想这就是性能缓慢的原因。我不知道出了什么问题,我在 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 年 7 月 23 日更新]
我想创建一个按钮列表,每个按钮对应 ctrl.getMarkers()
中的 marker
。让我们假设一个标记是这样的
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]
我找到了解决方案,并在下面回答了我自己的问题。但是我仍然有一个问题,反应变慢了:"Deprecated attempt to access property 'nodeType' on a non-Node object"。请查看下面我的回答以获取有关该错误的更多信息。谢谢
我想出了如何(几乎)解决我的问题。我将控制器作为反应元素的属性传递,因此我可以调用它的功能。像这样:
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慢得多。我不知道为什么。查看控制台,我从 angular.js:328 收到一堆错误 "Deprecated attempt to access property 'nodeType' on a non-Node object"
,我想这就是性能缓慢的原因。我不知道出了什么问题,我在 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 不可能对新旧对象进行比较,导致缓慢和错误。