我有一个数组,该数组在AJAX调用后收到了前端React组件。该数组不过是从后端发送的带注释的列表,该列表表示Django-Treebeard模型数据。带注释的列表是物化路径树,它以平面数组的形式构造嵌套树的所有节点。
以下是前端反应中可用的确切数据:
const data = [
{
info: { close: [], open: true, level: 1 },
spot: {
id: 2,
path: "00020002",
depth: 2,
numchild: 0,
landmark_name: "Metrolink Trafford Depot",
distance: "700.00",
unit: "m",
child: 0
}
},
{
info: { close: [], open: false, level: 1 },
spot: {
id: 3,
path: "00020003",
depth: 2,
numchild: 0,
landmark_name: "Bus Stand",
distance: "300.00",
unit: "m",
child: 0
}
},
{
info: { close: [], open: false, level: 1 },
spot: {
id: 4,
path: "00020005",
depth: 2,
numchild: 2,
landmark_name: "Restaurants and Bars",
distance: null,
unit: null,
child: 1
}
},
{
info: { close: [], open: true, level: 2 },
spot: {
id: 5,
path: "000200050001",
depth: 3,
numchild: 2,
landmark_name: "Trafford Bar",
distance: 650.00,
unit: "m",
child: 1
}
},
{
info: { close: ["0"], open: false, level: 2 },
spot: {
id: 6,
path: "000200050003",
depth: 3,
numchild: 0,
landmark_name: "Café Hardrock",
distance: "1.50 ",
unit: "km",
child: 0
}
},
{
info: { close: [], open: false, level: 1 },
spot: {
id: 8,
path: "00020008",
depth: 2,
numchild: 1,
landmark_name: "Hospital",
distance: null,
unit: null,
child: 1
}
},
{
info: { close: ["0", "1", "2"], open: true, level: 2 },
spot: {
id: 14,
path: "000200080001",
depth: 3,
numchild: 0,
landmark_name: "Seymour Grove Health Centre",
distance: "320.00",
unit: "m",
child: 0
}
}
];
后端的实际数据树是:
Root
|_ Metrolink Trafford Depot: 700m
|_Bus Stand: 300
|_Restaurant and Bars:
|_Trafford Bar : 650m
|_ Café Hardrock: 1.5km
|_ Hospital:
|_ Seymour Grove Health Centre: 320m
我想创建表示上面层次结构的嵌套div结构,如下所示:
<div>
<h3> MetroLink Trafford Depot :</h3>
<p> 700m </p>
</div>
<div>
<h3> Bus Stand:</h3>
<p>300m </p>
</div>
<div>
<h3> Restaurants and Bars:</h3>
<div>
<h4> Trafford Bar:</h4>
<p> 650m</p>
</div>
<div>
<h4> Café Hardrock:</h4>
<p> 1.5km</p>
</div>
</div>
<div>
<h3> Hospital:</h3>
<div>
<h4> Seymour Grove Health Centre:</h4>
<p>320m</p>
</div>
</div>
我尝试过递归,但失败了。甚至没有达到我的预期。 我尝试搜索第三方解决方案,但它们需要完全不同的数据结构。我不想更改后端的数据结构。我刚经历过的另一个地狱。另外,我认为物化路径树更适合后端效率。
如何编写React组件以根据给定数据生成以上HTML结构?
答案 0 :(得分:1)
您可以首先使用@objc func appEnteredBackgound() {
if let tracks = player?.currentItem?.tracks {
for track in tracks {
if (track.assetTrack?.hasMediaCharacteristic(AVMediaCharacteristic.visual))! {
track.isEnabled = false
}
}
}
}
@objc func appEnteredForeground() {
if let tracks = player?.currentItem?.tracks {
for track in tracks {
if (track.assetTrack?.hasMediaCharacteristic(AVMediaCharacteristic.visual))! {
track.isEnabled = true
}
}
}
}
属性(将其拆分为4个字符的块)从中创建嵌套的对象结构。一旦有了,就可以使用递归来创建HTML元素:
public class MainActivity extends AppCompatActivity {
private static Button button, butto2,reset_bu, auto;
private static ImageView imageView;
private static TextView textView;
private int i=0;
private Handler handler = new Handler();
// image resource
int[] images = {R.drawable.im_1, R.drawable.im_2, R.drawable.im_3,
R.drawable.im_24, R.drawable.im_25, R.drawable.im_26,
R.drawable.im_27, R.drawable.im_28, R.drawable.im_29,
R.drawable.im_30, R.drawable.im_31, R.drawable.im_32,
R.drawable.im_33, R.drawable.im_34, R.drawable.im_35,
R.drawable.im_36, R.drawable.im_37, R.drawable.im_38,
R.drawable.im_39, R.drawable.im_40, R.drawable.im_41,
R.drawable.im_42, R.drawable.im_43, R.drawable.im_44,
R.drawable.im_45,};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
butto2 = (Button) findViewById(R.id.button2);
reset_bu = (Button) findViewById(R.id.reset_bu);
final TextView textView = (TextView) findViewById(R.id.textView);
// auto = (Button) findViewById(R.id.auto);
// imageView = (ImageView) findViewById(R.id.imageView);
addListenerOnButton();
setInitialImage();
addback();
reset();
}
public void addListenerOnButton () {
button.setOnClickListener(new OnClickListener() {
@Override public void onClick(View v) {
if (i < images.length -1){
i++;
i = i % images.length;
setCurrentImage();
}
} });
}
private void setInitialImage() {
setCurrentImage();
}
private void setCurrentImage() {
final ImageView imageView = (ImageView) findViewById(R.id.imageView);
imageView.setImageResource(images[i]);
final TextView textView=(TextView)findViewById(R.id.textView);
final HashMap<Integer, Integer> map = new HashMap<>();
map.put(R.drawable.im_1, R.string.busort);
map.put(R.drawable.im_2, R.string.busort2);
int busort = map.get(R.drawable.im_1);
int busort2 = map.get(R.drawable.im_2);
int busort3 = map.get(R.drawable.im_3);
String text1 = getResources().getString(busort);
String text12 = getResources().getString(busort2);
textView.setText(busort);
textView.setText(busort2);
}
public void addback(){
butto2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (i > 0){
i--;
i = i % images.length;
setCurrentImage();
}
}
});
}
public void reset(){
reset_bu.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
i=0;
setCurrentImage();
}
});
}
}
path
class Tree extends React.Component {
constructor(props) {
super(props);
this.state = { data: props.data }
}
render() {
// Create nested tree structure from data
let root = { children: {} };
for (let {spot} of this.state.data) {
let node = root;
for (let child of spot.path.match(/..../g)) {
if (!(child in node.children)) node.children[child] = { children: {} };
node = node.children[child];
}
node.name = spot.landmark_name;
if (spot.distance) node.distance = String(+spot.distance) + spot.unit;
}
// Create elements from tree
const e = React.createElement;
return (function recur(node, level=1) {
let children = Object.values(node.children).map(child => recur(child, level+1));
if (children.length === 1 && !node.name) return children[0];
if (!children.length) children = [e("p", null, node.distance)];
if (node.name) children.unshift(e("h" + level, null, node.name));
return e("div", null, ...children);
})(root);
}
}
// Sample data from the question:
const data = [{info: { close: [], open: true, level: 1 },spot: {id: 2,path: "00020002",depth: 2,numchild: 0,landmark_name: "Metrolink Trafford Depot",distance: "700.00",unit: "m",child: 0}},{info: { close: [], open: false, level: 1 },spot: {id: 3,path: "00020003",depth: 2,numchild: 0,landmark_name: "Bus Stand",distance: "300.00",unit: "m",child: 0}},{info: { close: [], open: false, level: 1 },spot: {id: 4,path: "00020005",depth: 2,numchild: 2,landmark_name: "Restaurants and Bars",distance: null,unit: null,child: 1}},{info: { close: [], open: true, level: 2 },spot: {id: 5,path: "000200050001",depth: 3,numchild: 2,landmark_name: "Trafford Bar",distance: 650.00,unit: "m",child: 1}},{info: { close: ["0"], open: false, level: 2 },spot: {id: 6,path: "000200050003",depth: 3,numchild: 0,landmark_name: "Café Hardrock",distance: "1.50 ",unit: "km",child: 0}},{info: { close: [], open: false, level: 1 },spot: {id: 8,path: "00020008",depth: 2,numchild: 1,landmark_name: "Hospital",distance: null,unit: null,child: 1}},{info: { close: ["0", "1", "2"], open: true, level: 2 },spot: {id: 14,path: "000200080001",depth: 3,numchild: 0,landmark_name: "Seymour Grove Health Centre",distance: "320.00",unit: "m",child: 0}}];
// Render
ReactDOM.render(React.createElement(Tree, {data}), document.body);