聚合物就绪函数仅调用一次
Polymer ready function called only once
我正在测试 Polymer 以开发一个我想在 html 中多次重复使用的组件(见下图)。我开发了以下元素:
<link rel="import" href="bower_components/polymer/polymer.html">
<script src="js/fabric.js"></script>
<dom-module id="tooth-element">
<template>
<style>
#labelWrapper {
display: flex;
justify-content: center;
align-items: center;
font-size: 35px;
font-weight: bold;
height: 40PX;
}
</style>
<div id="toothWrapper">
<div id="upperRootWrapper">
<canvas id="upperRoot" />
</div>
<div>
<canvas id="tooth" />
</div>
<div id="lowerRootWrapper">
<canvas id="lowerRoot" />
</div>
<div id="labelWrapper">
<p>{{toothLabel}}</p>
</div>
</div>
</template>
<script>
var TOOTH_SIZE = 50;
var TOOTH_GAP = 5;
var UPPERROOTID = 'upperRoot';
var LOWERROOTID = 'lowerRoot';
var TOOTHID = 'tooth';
Polymer({
is: "tooth-element",
properties: {
// declare the owner property
showUpperRoot: {
type: Boolean,
value: true
},
showLowerRoot: {
type: Boolean,
value: true
},
toothLabel: {
type: String,
value: 30
}
},
ready: function() {
drawUpperRoot(this.showUpperRoot);
drawTooth();
drawLowerRoot(this.showLowerRoot);
initLabel(this.toothLabel);
}
});
function initLabel (label) {
document.getElementById("labelWrapper").style.width = new String(3*TOOTH_SIZE)+'px';
}
function drawUpperRoot (isVisible) {
var canvas = new fabric.Canvas(UPPERROOTID);
if (isVisible) {
canvas.setHeight(TOOTH_SIZE+TOOTH_GAP);
canvas.setWidth(TOOTH_SIZE*3+TOOTH_GAP);
canvas.renderAll();
canvas.add(drawFace(1));
} else {
document.getElementById("upperRootWrapper").style.display = "none";
}
}
function drawTooth () {
var canvas = new fabric.Canvas(TOOTHID);
canvas.setHeight(TOOTH_SIZE*3+TOOTH_GAP*2);
canvas.setWidth(TOOTH_SIZE*3+TOOTH_GAP*2);
canvas.renderAll();
canvas.add(drawFace(2));
canvas.add(drawFace(3));
canvas.add(drawFace(4));
canvas.add(drawFace(5));
canvas.add(drawFace(6));
//canvas.add(drawFace(7));
}
function drawLowerRoot (isVisible) {
var canvas = new fabric.Canvas(LOWERROOTID);
if (isVisible) {
canvas.setHeight(TOOTH_SIZE+TOOTH_GAP*2);
canvas.setWidth(TOOTH_SIZE*3+TOOTH_GAP*2);
canvas.renderAll();
canvas.add(drawFace(7));
} else {
document.getElementById("lowerRootWrapper").style.display = "none";;
}
}
function drawFace(face) {
var coordinates;
switch (face) {
case 1:
coordinates = getFace1Coordinates();
break;
case 2:
coordinates = getFace2Coordinates();
break;
case 3:
coordinates = getFace3Coordinates();
break;
case 4:
coordinates = getFace4Coordinates();
break;
case 5:
coordinates = getFace5Coordinates();
break
case 6:
coordinates = getFace6Coordinates();
break;
case 7:
coordinates = getFace7Coordinates();
break;
default:
coorddinates = null;
}
face = new fabric.Polygon(coordinates, {
fill: '#E1E1E1',
selectable: false,
stroke: 'green'
});
face.on('mousedown', function () {
if (face.fill == '#E1E1E1') {
face.fill = '#878787';
} else {
face.fill = '#E1E1E1';
}
});
return face;
}
function getFace1Coordinates() {
return [{x: TOOTH_SIZE, y: 0}, {x: TOOTH_SIZE*2+TOOTH_GAP, y: 0}, {x: TOOTH_SIZE*3+TOOTH_GAP, y: TOOTH_SIZE}, {x: 0, y: TOOTH_SIZE}];
}
function getFace2Coordinates() {
return [{x: 0, y: TOOTH_GAP}, {x: TOOTH_SIZE, y: TOOTH_SIZE+TOOTH_GAP}, {x: TOOTH_SIZE, y: TOOTH_SIZE*2+TOOTH_GAP}, {x: 0, y: TOOTH_SIZE*3}];
}
function getFace3Coordinates() {
return [{x: 0, y: 0}, {x: TOOTH_SIZE, y: TOOTH_SIZE}, {x: TOOTH_SIZE*2, y: TOOTH_SIZE}, {x: TOOTH_SIZE*3, y: 0}];
}
function getFace4Coordinates() {
return [{x: TOOTH_SIZE*3+TOOTH_GAP, y: 0}, {x: TOOTH_SIZE*2+TOOTH_GAP, y: TOOTH_SIZE}, {x: TOOTH_SIZE*2+TOOTH_GAP, y: TOOTH_SIZE*2+TOOTH_GAP}, {x: TOOTH_SIZE*3+TOOTH_GAP, y: TOOTH_SIZE*3}];
}
function getFace5Coordinates() {
return [{x: 0, y: TOOTH_SIZE*3+TOOTH_GAP}, {x: TOOTH_SIZE+TOOTH_GAP, y: TOOTH_SIZE*2+TOOTH_GAP}, {x: TOOTH_SIZE*2, y: TOOTH_SIZE*2+TOOTH_GAP}, {x: TOOTH_SIZE*3+TOOTH_GAP, y: TOOTH_SIZE*3+TOOTH_GAP}];
}
function getFace6Coordinates() {
return [{x: TOOTH_SIZE+TOOTH_GAP, y: TOOTH_SIZE+TOOTH_GAP}, {x: TOOTH_SIZE*2, y: TOOTH_SIZE+TOOTH_GAP}, {x: TOOTH_SIZE*2, y: TOOTH_SIZE*2}, {x: TOOTH_SIZE+TOOTH_GAP, y: TOOTH_SIZE*2}];
}
function getFace7Coordinates() {
return [{x: 0, y: 0}, {x: TOOTH_SIZE, y: TOOTH_SIZE}, {x: TOOTH_SIZE*2, y: TOOTH_SIZE}, {x: TOOTH_SIZE*3, y: 0}];
}
</script>
</dom-module>
我正在尝试将其导入到 index.html 文件中:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="tooth-element.html">
</head>
<body>
<div id="line1">
<tooth-element></tooth-element>
<tooth-element></tooth-element>
</div>
</body>
</html>
当我在 div 行 1 中放置两个牙齿元素时出现问题。第二个元素从不显示,因为从不为它调用 ready 函数。我不知道我应该怎么做才能解决这个问题。任何帮助将不胜感激
我想在 html 中重复的组件布局如下所示(我得到的是第一个牙齿元素的图像,但不是第二个牙齿元素):
(解决方案)
我没有正确使用 DOM(正如 Neil John Ramal 所解释的)。使用 Glenn 和 Neil 关于使用 Poly.dom API 的建议,我能够得到我想要的行为
在处理本地 DOM(即 document.getElementById
、document.querySelector
等)时,请尽量避免使用常规 DOM API .请改用 Polymer.dom
。请注意,当您将 Polymer 设置为使用 Shadow DOM 而不是 Shady DOM 时,您的代码可能会失败,因为常规 DOM 访问器无法穿透 Shadow DOM (封装是它的特征之一,Shady DOM 试图接近它)。
代码中的一个问题是生成的元素与某些全局对象紧密耦合(例如 drawUpperRoot
)。这实质上破坏了您的元素封装,因为此代码也将被该元素的其他实例使用,因此您基本上是让它们依赖于全局范围,而不是使用它们自己的范围。
还有这个代码:
function initLabel (label) {
document.getElementById("labelWrapper").style.width = new String(3*TOOTH_SIZE)+'px';
}
意味着当您创建两个 tooth-element
时,第二个元素基本上会引用第一个元素的 labelWrapper
而不是它自己的。
https://www.polymer-project.org/1.0/docs/devguide/local-dom.html
document.querySelector() return 它在文档中找到的第一个元素,第二个被忽略。
将文档更改为此应该可以解决问题。
document.querySelector('#labelWrapper') -> this.querySelector(#labelWrapper)
或
document.querySelector('#labelWrapper') -> Polymer.dom(this).querySelector('#labelWrapper')
我正在测试 Polymer 以开发一个我想在 html 中多次重复使用的组件(见下图)。我开发了以下元素:
<link rel="import" href="bower_components/polymer/polymer.html">
<script src="js/fabric.js"></script>
<dom-module id="tooth-element">
<template>
<style>
#labelWrapper {
display: flex;
justify-content: center;
align-items: center;
font-size: 35px;
font-weight: bold;
height: 40PX;
}
</style>
<div id="toothWrapper">
<div id="upperRootWrapper">
<canvas id="upperRoot" />
</div>
<div>
<canvas id="tooth" />
</div>
<div id="lowerRootWrapper">
<canvas id="lowerRoot" />
</div>
<div id="labelWrapper">
<p>{{toothLabel}}</p>
</div>
</div>
</template>
<script>
var TOOTH_SIZE = 50;
var TOOTH_GAP = 5;
var UPPERROOTID = 'upperRoot';
var LOWERROOTID = 'lowerRoot';
var TOOTHID = 'tooth';
Polymer({
is: "tooth-element",
properties: {
// declare the owner property
showUpperRoot: {
type: Boolean,
value: true
},
showLowerRoot: {
type: Boolean,
value: true
},
toothLabel: {
type: String,
value: 30
}
},
ready: function() {
drawUpperRoot(this.showUpperRoot);
drawTooth();
drawLowerRoot(this.showLowerRoot);
initLabel(this.toothLabel);
}
});
function initLabel (label) {
document.getElementById("labelWrapper").style.width = new String(3*TOOTH_SIZE)+'px';
}
function drawUpperRoot (isVisible) {
var canvas = new fabric.Canvas(UPPERROOTID);
if (isVisible) {
canvas.setHeight(TOOTH_SIZE+TOOTH_GAP);
canvas.setWidth(TOOTH_SIZE*3+TOOTH_GAP);
canvas.renderAll();
canvas.add(drawFace(1));
} else {
document.getElementById("upperRootWrapper").style.display = "none";
}
}
function drawTooth () {
var canvas = new fabric.Canvas(TOOTHID);
canvas.setHeight(TOOTH_SIZE*3+TOOTH_GAP*2);
canvas.setWidth(TOOTH_SIZE*3+TOOTH_GAP*2);
canvas.renderAll();
canvas.add(drawFace(2));
canvas.add(drawFace(3));
canvas.add(drawFace(4));
canvas.add(drawFace(5));
canvas.add(drawFace(6));
//canvas.add(drawFace(7));
}
function drawLowerRoot (isVisible) {
var canvas = new fabric.Canvas(LOWERROOTID);
if (isVisible) {
canvas.setHeight(TOOTH_SIZE+TOOTH_GAP*2);
canvas.setWidth(TOOTH_SIZE*3+TOOTH_GAP*2);
canvas.renderAll();
canvas.add(drawFace(7));
} else {
document.getElementById("lowerRootWrapper").style.display = "none";;
}
}
function drawFace(face) {
var coordinates;
switch (face) {
case 1:
coordinates = getFace1Coordinates();
break;
case 2:
coordinates = getFace2Coordinates();
break;
case 3:
coordinates = getFace3Coordinates();
break;
case 4:
coordinates = getFace4Coordinates();
break;
case 5:
coordinates = getFace5Coordinates();
break
case 6:
coordinates = getFace6Coordinates();
break;
case 7:
coordinates = getFace7Coordinates();
break;
default:
coorddinates = null;
}
face = new fabric.Polygon(coordinates, {
fill: '#E1E1E1',
selectable: false,
stroke: 'green'
});
face.on('mousedown', function () {
if (face.fill == '#E1E1E1') {
face.fill = '#878787';
} else {
face.fill = '#E1E1E1';
}
});
return face;
}
function getFace1Coordinates() {
return [{x: TOOTH_SIZE, y: 0}, {x: TOOTH_SIZE*2+TOOTH_GAP, y: 0}, {x: TOOTH_SIZE*3+TOOTH_GAP, y: TOOTH_SIZE}, {x: 0, y: TOOTH_SIZE}];
}
function getFace2Coordinates() {
return [{x: 0, y: TOOTH_GAP}, {x: TOOTH_SIZE, y: TOOTH_SIZE+TOOTH_GAP}, {x: TOOTH_SIZE, y: TOOTH_SIZE*2+TOOTH_GAP}, {x: 0, y: TOOTH_SIZE*3}];
}
function getFace3Coordinates() {
return [{x: 0, y: 0}, {x: TOOTH_SIZE, y: TOOTH_SIZE}, {x: TOOTH_SIZE*2, y: TOOTH_SIZE}, {x: TOOTH_SIZE*3, y: 0}];
}
function getFace4Coordinates() {
return [{x: TOOTH_SIZE*3+TOOTH_GAP, y: 0}, {x: TOOTH_SIZE*2+TOOTH_GAP, y: TOOTH_SIZE}, {x: TOOTH_SIZE*2+TOOTH_GAP, y: TOOTH_SIZE*2+TOOTH_GAP}, {x: TOOTH_SIZE*3+TOOTH_GAP, y: TOOTH_SIZE*3}];
}
function getFace5Coordinates() {
return [{x: 0, y: TOOTH_SIZE*3+TOOTH_GAP}, {x: TOOTH_SIZE+TOOTH_GAP, y: TOOTH_SIZE*2+TOOTH_GAP}, {x: TOOTH_SIZE*2, y: TOOTH_SIZE*2+TOOTH_GAP}, {x: TOOTH_SIZE*3+TOOTH_GAP, y: TOOTH_SIZE*3+TOOTH_GAP}];
}
function getFace6Coordinates() {
return [{x: TOOTH_SIZE+TOOTH_GAP, y: TOOTH_SIZE+TOOTH_GAP}, {x: TOOTH_SIZE*2, y: TOOTH_SIZE+TOOTH_GAP}, {x: TOOTH_SIZE*2, y: TOOTH_SIZE*2}, {x: TOOTH_SIZE+TOOTH_GAP, y: TOOTH_SIZE*2}];
}
function getFace7Coordinates() {
return [{x: 0, y: 0}, {x: TOOTH_SIZE, y: TOOTH_SIZE}, {x: TOOTH_SIZE*2, y: TOOTH_SIZE}, {x: TOOTH_SIZE*3, y: 0}];
}
</script>
</dom-module>
我正在尝试将其导入到 index.html 文件中:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="tooth-element.html">
</head>
<body>
<div id="line1">
<tooth-element></tooth-element>
<tooth-element></tooth-element>
</div>
</body>
</html>
当我在 div 行 1 中放置两个牙齿元素时出现问题。第二个元素从不显示,因为从不为它调用 ready 函数。我不知道我应该怎么做才能解决这个问题。任何帮助将不胜感激
我想在 html 中重复的组件布局如下所示(我得到的是第一个牙齿元素的图像,但不是第二个牙齿元素):
(解决方案) 我没有正确使用 DOM(正如 Neil John Ramal 所解释的)。使用 Glenn 和 Neil 关于使用 Poly.dom API 的建议,我能够得到我想要的行为
在处理本地 DOM(即 document.getElementById
、document.querySelector
等)时,请尽量避免使用常规 DOM API .请改用 Polymer.dom
。请注意,当您将 Polymer 设置为使用 Shadow DOM 而不是 Shady DOM 时,您的代码可能会失败,因为常规 DOM 访问器无法穿透 Shadow DOM (封装是它的特征之一,Shady DOM 试图接近它)。
代码中的一个问题是生成的元素与某些全局对象紧密耦合(例如 drawUpperRoot
)。这实质上破坏了您的元素封装,因为此代码也将被该元素的其他实例使用,因此您基本上是让它们依赖于全局范围,而不是使用它们自己的范围。
还有这个代码:
function initLabel (label) {
document.getElementById("labelWrapper").style.width = new String(3*TOOTH_SIZE)+'px';
}
意味着当您创建两个 tooth-element
时,第二个元素基本上会引用第一个元素的 labelWrapper
而不是它自己的。
https://www.polymer-project.org/1.0/docs/devguide/local-dom.html
document.querySelector() return 它在文档中找到的第一个元素,第二个被忽略。
将文档更改为此应该可以解决问题。
document.querySelector('#labelWrapper') -> this.querySelector(#labelWrapper)
或
document.querySelector('#labelWrapper') -> Polymer.dom(this).querySelector('#labelWrapper')