我想创建一个通用 Polymer 组件,它为子组件中数据元素的每个实例调用父 Polymer 组件中的回调函数。
这是一般父级:
<dom-module id="nested-parent">
<template>
<style>
:host {
display: block;
}
</style>
<nested-child callback="nodedesign(node)"></nested-child>
</template>
<script>
Polymer({
is: 'nested-parent',
properties: {
},
nodedesign: function(node) {
}
});
</script>
</dom-module>
这是一般的 child :
<dom-module id="nested-child">
<template>
<style>
:host {
display: block;
}
</style>
</template>
<script>
Polymer({
is: 'nested-child',
properties: {
callback: {
type: String
}
}
});
</script>
</dom-module>
我希望 Node 子 Node 为子 Node 中的每个 Node 实例调用 node-parent
组件中的 nodedesign(node) {}
函数。
更新:
我正在尝试创建一个 d3 力图组件,其父元素将具有绘制 Node 和链接的功能,因此常规缩放和平移功能位于常规组件中。
<link rel="import" href="../../bower_components/polymer/polymer.html"/>
<script src="../../bower_components/d3/d3.min.js"></script>
<dom-module id="d3-graph">
<template>
<style>
</style>
<div id="generalGraph"></div>
</template>
<script>
var d3graphSVG;
Polymer({
is: "d3-graph",
properties: {
graph: { type: Object, notify: true, observer: '_graphChanged' }
},
ready: function() {
this.scopeSubtree(this.$.generalGraph, true);
d3graphSVG = d3.select(this.$.generalGraph).append("svg")
.attr("width", "100%")
.attr("height", "100%");
},
_graphChanged: function() {
if (this.graph == null) return;
if (this.graph.nodes.length == 0) return;
var width = 800;
var height = 800;
this.scopeSubtree(this.$.generalGraph, true);
var force = d3.layout.force()
.gravity(0.05)
.distance(100)
.charge(function(d) { return (d.mode == 1) ? 50 : -100;})
.size([width, height]);
force
.nodes(this.graph.nodes)
.links(this.graph.links)
.start();
var link = d3graphSVG.selectAll(".link")
.data(this.graph.links)
.enter().append("line")
.attr("class", "link");
var node = d3graphSVG.selectAll(".node")
.data(this.graph.nodes)
.enter().append("g")
.attr("class", "node")
.on("click", function(d) {
console.log("foo");
})
.call(force.drag);
node.append("image")
.attr("xlink:href", "https://github.com/favicon.ico")
.attr("x", -8)
.attr("y", -8)
.attr("width", 16)
.attr("height", 16);
node.append("text")
.attr("dx", 12)
.attr("dy", ".35em")
.text(function(d) { return d.name });
force.on("tick", function() {
link.attr("x1", function(d) {
if (d.source.mode == 1) { d.source.x = 50; }
return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) {
if (d.target.mode == 1) { d.target.x = 50; }
return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node.attr("transform", function(d) {
if (d.mode == 1) {
d.fixed = true;
d.x = 50;
}
return "translate(" + d.x + "," + d.y + ")";
});
});
}
})
</script>
</dom-module>
以下内容将位于父级中的函数中,该函数将根据数据内容绘制 Node :
var node = d3graphSVG.selectAll(".node")
.data(this.graph.nodes)
.enter().append("g")
.attr("class", "node")
.on("click", function(d) {
console.log("foo");
})
.call(force.drag);
node.append("image")
.attr("xlink:href", "https://github.com/favicon.ico")
.attr("x", -8)
.attr("y", -8)
.attr("width", 16)
.attr("height", 16);
node.append("text")
.attr("dx", 12)
.attr("dy", ".35em")
.text(function(d) { return d.name });
其他更新:
我将尝试在父级中向数据添加函数:
graph.nodes.forEach( function (node)
{
node._draw = function() {
return '<g class="node"><image xlink:href="https://github.com/favicon.ico" x="-8" y="-8" width="16" height="16"></image><text dx="12" dy=".35em">'
+ this.name + '</text></g>'
};
});
并将子组件功能代码更改为:
var node = d3graphSVG.selectAll(".node")
.data(this.graph.nodes)
.enter().html(this._draw()).call(force.drag);
最佳答案
您的想法是错误的,子元素不应该属于父元素,因为它不能重用。更好的方法是让 child 有一个通知属性:
properties: {
data: {type:Object, notify: true}
}
并且在父元素中监听它使用事件监听器更改了事件eather:
this.addEventListener('data-changed', this.nodedesign.bind(this));
nodedesign: ( event ) => {
// event.detail should have the data and the element in it
let item = event.detail.item;
let data = event.detail.data;
},
或者使用 polymer 数据绑定(bind)系统:
<nested-child data="{{parentData}}"></nested-child>
properties: {
parentData: {type: Object, observer: 'nodedesign'}
},
nodedesign: ( newValue, oldValue ) => {
// do stuff
},
当然,你可以通过一些小技巧来调用父函数,但我不推荐这样做:
let parent = null;
while ((parent = parent.parentElement) && parent.tagName != 'NESTED-PARENT');
if( parent != null ) parent.nodedesign( this )
关于javascript - 希望将带有参数的回调函数传递给 Polymer 中的子组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39735125/