Javascript 角度:样式或类别绑定,座位地图
我正在为我的研究生学习项目而奋斗。我需要使互动座位地图的角度与最大选择9个座位。在浏览了我以前的课程之后,我能够在JS中创造一些魔力,但没有max selection(下面链接到codepen) HTML代码包含巨大的SVG图形-您可以在下面附带的代码笔中找到它 CSS JavascriptJavascript 角度:样式或类别绑定,座位地图,javascript,css,angular,typescript,Javascript,Css,Angular,Typescript,我正在为我的研究生学习项目而奋斗。我需要使互动座位地图的角度与最大选择9个座位。在浏览了我以前的课程之后,我能够在JS中创造一些魔力,但没有max selection(下面链接到codepen) HTML代码包含巨大的SVG图形-您可以在下面附带的代码笔中找到它 CSS Javascript const buttonArray = document.querySelectorAll("#seats path"); console.log("query", typeof buttonArray);
const buttonArray = document.querySelectorAll("#seats path");
console.log("query", typeof buttonArray);
var myArray = Array.from(buttonArray);
console.log(myArray);
for (let i = 0; i < myArray.length; i++) {
myArray[i].setAttribute("id", `seat_${i + 1}`);
document.getElementById(`seat_${i + 1}`).addEventListener("click", function() {
if (document.getElementById(this.id).getAttribute("class") == "occupied") {
document.getElementById(this.id).removeAttribute("style");
document.getElementById(this.id).setAttribute("class", "free");
} else {
document.getElementById(this.id).removeAttribute("style");
document.getElementById(this.id).setAttribute("class", "occupied");
}
});
}
const buttonArray=document.queryselectoral(“座位路径”);
console.log(“查询”,按钮数组的类型);
var myArray=Array.from(buttonArray);
log(myArray);
for(设i=0;i
我不知道如何将其实现为Angular,或者如何使其更简单。
当然,如何最大限度地选择9个座位
我将非常感谢你的任何建议和帮助
您可以将onClick函数添加到path=seats
<g id="seats" (click)="onClick($event)">
为什么不使用角呢
我们将定义一个指令,但是如果修改svg以将座椅分组(而不是将字母和背景分开),我们需要做的第一件事是
一个座位就变成这样了
<g seat id="26F" >
<path #background class="st121" d="M285.8,1126.1h-17c-0.6,0-1-0.4-1-1v-22c0-0.6,0.4-1,1-1h17c0.6,0,1,0.4,1,1v22
C286.8,1125.7,286.3,1126.1,285.8,1126.1z "/>
<path #letter class="st122" d="M275.8,1115.2v-6.4h4.2v1.2h-2.9v1.7h2.6v1.1h-2.6v2.5L275.8,1115.2L275.8,1115.2z"></path>
</g>
注意不要在一个“组”中放置两条路径
我写
。是属性指令。还可以看到,我们使用了两个参考变量,一个用于背景,另一个用于字母
指令变得像
@Directive({
selector: '[seat]',
exportAs: 'seat'
})
export class SeatDirective {
@ContentChild('background') background:ElementRef //<--reference to background
@ContentChild('letter') letter:ElementRef //<--reference to letter
@HostListener('click', ['$event.target']) //<--a HostListener
onClick() //when click
{
this.seatmap.seatClick(this) //call to a funcion of the "seatmap"
}
checked:boolean=false //a variable that store if checked or not
constructor(public el:ElementRef,@Host() private seatmap:SeatmapComponent ){}
}
@指令({
选择器:“[座位]”,
exportAs:'座位'
})
出口级定向{
@ContentChild('background')背景:ElementRef//x.checked)
.map(x=>x.el.nativeElement.getAttribute('id'))
}
另一种方法是“动态”创建座位,使用数组放置位置,并在svg中使用rect和文本
如果我们有一个行数组
filas = [
{ y: 250, x: [0, 0, 0, 195.5, 175.2, 154.8] },
{ y: 281.9, x: [285.8, 265.5, 245.1, 195.5, 175.2, 154.8] },
{ y: 313.9, x: [285.8, 265.5, 245.1, 195.5, 175.2, 154.8] },
{ y: 345.9, x: [285.8, 265.5, 245.1, 195.5, 175.2, 154.8] },
...
]
我们可以动态创建svg,如果我们使用0作为coordenate,就不要创建座位
<svg version="1.1" id="whole_x5F_plane" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 425 1467.9" style="enable-background:new 0 0 425 1467.9;" xml:space="preserve">
<style type="text/css">
.st0{clip-path:url(#SVGID_15_);}
.st1{clip-path:url(#SVGID_24_);}
...
.free{fill:#FFFFFF;stroke:#050404;stroke-width:0.25;stroke-miterlimit:10;}
.booked{fill:#8E8E8E;stroke:#050404;stroke-width:0.25;stroke-miterlimit:10;}
.selected{fill:#FFFF00;stroke:#050404;stroke-width:0.25;stroke-miterlimit:10;}
</style>
...
<ng-container *ngFor="let fila of filas;let i=index">
<ng-container *ngFor="let x of fila.x;let j=index">
<!--if x==0 don't create the seat-->
<g style="cursor:pointer" *ngIf="x" (click)="click(i,j)">
<!--a rectangle-->
<rect [ngClass]="status[i][j]" [attr.x]="x-18" [attr.y]="fila.y-22" width="20" height="20" rx="2"
ry="2" />
<!--and the text-->
<text [attr.x]="x-16" [attr.y]="fila.y-8" font-family="Verdana"
font-size="11" stroke="transparent"
fill="#333">
{{this.letras[j]}}
</text>
</g>
</ng-container>
</ng-container>
</svg>
.st0{clip path:url(#SVGID_15)}
.st1{剪辑路径:url(#SVGID_24)}
...
.free{fill:#FFFFFF;笔划:#050404;笔划宽度:0.25;笔划斜接限制:10;}
.booked{fill:#8E8E8E;笔划:#050404;笔划宽度:0.25;笔划斜接限制:10;}
.所选{填充:#FFFF00;笔划:#050404;笔划宽度:0.25;笔划斜接限制:10;}
...
{{this.letras[j]}
因为我们在svg中有预订、免费、选择的类,点击变得很容易,记住我们使用数组数组来存储座位的“类”
status = this.filas.map(x => [
"free",
"free",
"free",
"free",
"free",
"free"
]);
click(fila, column) {
if (this.status[fila][column] == "free" && this.count() < 3) //here check the maximum
this.status[fila][column] = "selected";
else {
if (this.status[fila][column] == "selected")
this.status[fila][column] = "free";
}
}
count() {
return this.status
.map(x => x.filter(s => s == "selected").length)
.reduce((a, b) => a + b);
}
status=this.filas.map(x=>[
“免费”,
“免费”,
“免费”,
“免费”,
“免费”,
“免费”
]);
单击(fila,列){
如果(this.status[fila][column]=“free”&&this.count()<3)//此处检查最大值
此.status[fila][column]=“已选定”;
否则{
如果(此状态[fila][column]=“已选定”)
此.status[fila][column]=“free”;
}
}
计数(){
返回此状态
.map(x=>x.filter(s=>s==“选定”).length)
.减少((a,b)=>a+b);
}
注意:我对数组的选择真的不是很满意,也许最好用行、字母、x、y和状态定义一个对象数组。但这是一个必须要做的事情天哪!非常感谢你!哇,当你写的时候,它变得简单易懂了。现在我可以开始处理max selection;)您知道如何将最大选择数9添加到您的解决方案中吗?这一切都很好,但我有几个问题。第一个:
如果(!seat){return;}
如果我错了,请更正。如果有人点击了与座位不同的东西,这是一种预防措施吗?第二个:const res=seat.getAttribute(“class”).split(“”).indexOf(“”)占用代码>为什么在这里使用split(“”)
,没有它代码仍然有效?1。第一个:如果(!seat){return;}如果我错了,请更正。如果有人点击了与座位不同的东西,这是一种预防措施吗?是的,你说得对。2.第二个:const res=seat.getAttribute(“class”).split(“”).indexOf(“”)占用;你为什么在这里使用split(“”),没有它代码仍然有效这是我的错。您不必使用split。我忘了我们也可以使用带字符串的拆分。这远远超过了我在课堂上学到的。关于开始时的分组问题,class=“st122”
指的是那些灰色字段,它们不是座位,更像是座位之间的空间。我不想把座位和字母的路径分组,因为我真的不知道哪个路径是哪个座位的->它们在代码中是随机定位的。@cichebonki,我回答了另一个问题,那就是创建“动态”座位,我希望能帮到你
<svg version="1.1" id="whole_x5F_plane" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 425 1467.9" style="enable-background:new 0 0 425 1467.9;" xml:space="preserve">
<style type="text/css">
.st0{clip-path:url(#SVGID_15_);}
.st1{clip-path:url(#SVGID_24_);}
...
.free{fill:#FFFFFF;stroke:#050404;stroke-width:0.25;stroke-miterlimit:10;}
.booked{fill:#8E8E8E;stroke:#050404;stroke-width:0.25;stroke-miterlimit:10;}
.selected{fill:#FFFF00;stroke:#050404;stroke-width:0.25;stroke-miterlimit:10;}
</style>
...
<ng-container *ngFor="let fila of filas;let i=index">
<ng-container *ngFor="let x of fila.x;let j=index">
<!--if x==0 don't create the seat-->
<g style="cursor:pointer" *ngIf="x" (click)="click(i,j)">
<!--a rectangle-->
<rect [ngClass]="status[i][j]" [attr.x]="x-18" [attr.y]="fila.y-22" width="20" height="20" rx="2"
ry="2" />
<!--and the text-->
<text [attr.x]="x-16" [attr.y]="fila.y-8" font-family="Verdana"
font-size="11" stroke="transparent"
fill="#333">
{{this.letras[j]}}
</text>
</g>
</ng-container>
</ng-container>
</svg>
status = this.filas.map(x => [
"free",
"free",
"free",
"free",
"free",
"free"
]);
click(fila, column) {
if (this.status[fila][column] == "free" && this.count() < 3) //here check the maximum
this.status[fila][column] = "selected";
else {
if (this.status[fila][column] == "selected")
this.status[fila][column] = "free";
}
}
count() {
return this.status
.map(x => x.filter(s => s == "selected").length)
.reduce((a, b) => a + b);
}