我正在使用ionic-angular和三个js开发一个Android应用程序。
我有一个组件实现了三个js(用于显示2d网格)和使用此组件的3个页面。
当我想用组件绘制东西时,我使用事件(发布/订阅)。有用 !但是,当我使用navMenu在页面之间切换并且重用一个事件时,旧页面的所有组件都会捕获该事件。
我认为使用nav时页面和子组件被破坏了,我认为是对的,该组件被调用ngOnDestroy()。但是它仍然捕获事件,因此我尝试取消订阅ngOnDestroy(),但现在没有任何组件捕获事件。
这是我的代码:
app.component.ts
export class MyApp {
@ViewChild("myNav") nav: NavController;
rootPage: any = LearnPage;
pages: Array<{title: string, component: any}>;
constructor(public platform: Platform, public statusBar: StatusBar, public splashScreen: SplashScreen) {
this.initializeApp();
this.pages = [
{ title: 'Learn', component: LearnPage },
{ title: 'Work', component: WorkPage},
{ title: 'Play', component: PlayPage}
];
}
initializeApp() {
this.platform.ready().then(() => {
this.statusBar.styleDefault();
this.splashScreen.hide();
});
}
openPage(page) {
this.nav.setRoot(page.component);
}
}
app.html:
<ion-menu [content]="content">
<ion-header>
<ion-toolbar>
<ion-title>Menu</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<button menuClose ion-item *ngFor="let p of pages" (click)="openPage(p)">
{{p.title}}
</button>
</ion-list>
</ion-content>
页面来源,当前3个页面相同: HTML:
<ion-header>
<ion-navbar>
<button ion-button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>Learn</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<div class="padding-default">
<grid class="canvas-disable"></grid>
</div>
<ion-item no-lines class="padding-default">
<ion-select class="default-select" [(ngModel)]="number" (ionChange)="onChange()">
<ion-option *ngFor="let number of numbers" [value]="number">{{number}} {{shape}}</ion-option>
</ion-select>
</ion-item>
</ion-content>
.ts:
export class LearnPage {
@ViewChild(Select) select: Select;
shape: string = shapeNames.SQUARE;
number: number = 1;
numbers: number[] = Array.from(Array(100),(x,i)=>i+1);
constructor(public events: Events, public eventNames: EventNames) {
}
ngAfterViewInit() {
this.events.publish(this.eventNames.GRID_COUNT, this.number, this.shape);
}
onChange() {
this.events.publish(this.eventNames.GRID_COUNT, this.number, this.shape);
}
}
和网格组件:HTML:
<div #rendererContainer></div>
.ts:
export class GridComponent {
@ViewChild('rendererContainer') rendererContainer: ElementRef;
canvasWidth: any;
grid: Shape[][];
color: number = 0xff0000;
renderer = new THREE.WebGLRenderer();
scene = null;
camera = null;
mesh = null;
constructor(public events: Events, public eventNames: EventNames) {
this.canvasWidth = window.innerWidth * 86 / 100;
this.grid = new Array<Array<Shape>>();
for (let y = 0; y < 10; y++) {
let row: Shape[] = new Array<Shape>();
for (let x = 0; x < 10; x++) {
row.push(new Shape(y * 10 + x));
}
this.grid.push(row);
}
this.scene = new THREE.Scene();
this.camera = new THREE.OrthographicCamera(0, this.canvasWidth, 0, this.canvasWidth, 1, 1000);
this.drawGrid();
this.events.subscribe(this.eventNames.GRID_COUNT, (x, s) => { this.count(x, s); });
console.log("Suscribe");
}
ngAfterViewInit() {
this.renderer.setSize(this.canvasWidth, this.canvasWidth);
this.rendererContainer.nativeElement.appendChild(this.renderer.domElement);
this.renderer.render(this.scene, this.camera);
}
ngOnDestroy() {
console.log("Grid ngOnDestroy");
this.events.unsubscribe(this.eventNames.GRID_COUNT);
}
drawGrid() {
let size = this.canvasWidth + 1;
let divisions = 10;
let gridHelper = new THREE.GridHelper(size, divisions, 0x000000, 0x000000);
gridHelper.rotation.x = Math.PI / 2;
gridHelper.position.z = -900;
gridHelper.position.x = this.canvasWidth / 2;
gridHelper.position.y = this.canvasWidth / 2;
this.scene.add(gridHelper);
let material = new THREE.MeshBasicMaterial({ color: 0xffffff, side: THREE.DoubleSide });
let plane = new THREE.Mesh(new THREE.PlaneGeometry(this.canvasWidth, this.canvasWidth), material);
plane.position.z = -1000;
plane.position.x = this.canvasWidth / 2;
plane.position.y = this.canvasWidth / 2;
this.scene.add(plane);
}
drawMesh(shape: Shape, x, y) {
let geometry = new THREE.BoxGeometry(this.canvasWidth / 11, this.canvasWidth / 11, this.canvasWidth / 11);
let material = new THREE.MeshBasicMaterial({ color: this.color });
this.mesh = new THREE.Mesh(geometry, material);
this.mesh.position.z = -100;
this.mesh.position.x = x * this.canvasWidth / 10 + this.canvasWidth / 20;
this.mesh.position.y = y * this.canvasWidth / 10 + this.canvasWidth / 20;
this.mesh.name = shape.id
shape.mesh = this.mesh;
this.scene.add(this.mesh);
this.renderer.render(this.scene, this.camera);
shape.filled = !shape.filled;
}
count(x: number, s: string) {
console.log("Count event received");
while (this.scene.children.length > 0) {
this.scene.remove(this.scene.children[0]);
}
this.drawGrid();
for (let i = 0; i < x; i++) {
this.drawMesh(this.grid[i % 10][Math.floor(i / 10)], i % 10, Math.floor(i / 10));
}
}
}
可能有些东西我误解或滥用了,谢谢您的阅读和帮助。
答案 0 :(得分:0)
我解决了我的问题。
在我的组件中,要获得宽度,请添加/删除我使用JQuery所做的类并设置动画。
let rowValues = $("#values")
let svgIndicator = $("svg#indicator")
let paragraphs = $(".bind-text")
选择器jquery错误,因为它将选择页面中的所有元素
这是结果
现在,我使用@ViewChild
和Renderer2
选择元素来添加/删除类。 jQuery只是为左svg制作动画
// HTML ELMENTS
@ViewChild('rowValues') rowValues: ElementRef
@ViewChild('indicator') svgIndicator: ElementRef
@ViewChildren('bindText') paragraphs:QueryList<ElementRef>
现在一切正常