Angular jQuery 的每个组件实例的 2 个唯一 ID
Angular 2 unique id for every component instance of jQuery
我有 Angular 2 组件包含 jquery 组件,我想为我的 Angular 2 组件的每个实例生成 id 因为我需要不同的 jquery 每个组件的选择器
这是我的组件
@Component({
selector: 'full-calendar',
templateUrl: 'full-calendar.html'
})
export class FullCalendarComponent {
ngOnChanges(changes: any) {
$('angular2-fullcalendar').fullCalendar('option',changes.options.currentValue)
}
}
我想每次使用多个不同的选择器
我找到了 this 解决方案
export class GetId {
protected getId(id: number|string = _.uniqueId()): string {
return _.lowerFirst(this.constructor.name) + '_' + id;
}
}
class MyComponent extends GetId {
...
}
id可以这样使用
<input [id]="getId('name')" type="text">
但我仍在寻找内置解决方案。
假设你有一个复选框,
<input class="styled-checkbox" id="{{checkboxId}}" type="checkbox">
<label for="{{checkboxId}}">{{checkboxLabel}}</label>
import { Component, Input } from '@angular/core';
@Component({
selector: 'checkbox',
templateUrl: './checkbox.component.html'
})
export class CheckboxComponent {
@Input() checkboxId:string;
@Input() checkboxLabel:string;
}
父级 -->
<checkbox [checkboxId]="Math.random().toString(36).substring(2)"></checkbox>
遍历 DOM:坏主意
您不应该使用 jQuery 遍历 DOM 并对其应用一些转换,原因如下:
Jquery 与 DOM 紧密耦合,而 angular 倾向于抽象所有这些交互:当您修改 angular 中的 DOM 时,您应该使用将对元素应用转换的 Renderer
API。这就是允许在 Worker 上渲染、构建 nativescript 应用程序等的原因。
如果要从父组件遍历 DOM 以应用修改,可能会出现一些问题:
- 某些元素可以通过 Angular 渲染器动态添加到 DOM 或从中删除。如何处理有条件渲染的元素?遍历每个变化检测是一种反模式。
- 当元素已被 angular 渲染器删除时,如何确保您应用在元素上的插件已被正确销毁?
有时候你确实需要jQuery
如果您确实需要使用 jQuery,例如在元素上应用 jQuery 插件,更好的做法是编写指令或组件并通过添加来应用插件模板中的指令或组件而不是从组件遍历 DOM。
您可以像这样创建一个指令:
注意:我对完整的日历没有概念API,所以完全是即兴创作。
@Directive({ selector: '[fullCalendar]' })
export class HighlightDirective implements OnInit,OnDestroy,OnChanges {
private jqElement:any;
constructor(private el: ElementRef) {
el.nativeElement.style.backgroundColor = 'yellow';
}
@Input()
options:any={};
ngOnInit(){
this.jqElement = $(this.el.nativeElement);
this.jqElement.fullCalendar(this.options);
}
ngOnChanges(changes:{[k:string]:SimpleChange}){
if(changes['options']&&!changes['options'].firstChange) // do not apply options on first change (jquery plugin not applied)
this.jqElement.fullCalendar("option",this.options);
}
ngOnDestroy(){
this.jqElement.fullCalendar("destroy");
}
}
并这样应用:
<div fullCalendar [options]="someOptions"></div>
一个简单而优雅的解决方案(找到了here)
let searchBoxId = 0;
@Component({
selector: 'app-auto-complete',
templateUrl: './auto-complete.component.html',
styleUrls: ['./auto-complete.component.less']
})
export class MyComponent implements AfterViewInit {
@Input() searchBoxId = `search-box-${searchBoxId++}`;
ngAfterViewInit(): void {
const searchBox = document.getElementById(`${this.searchBoxId}`);
// Get your input unique id
console.log("searchBox: ")
}
}
- 设置全局变量
- 每次使用(加载)组件时 - 我们计算变量
- 确保您从 DOM 获取唯一 ID,仅在加载后 (ngAfterViewInit)
我有 Angular 2 组件包含 jquery 组件,我想为我的 Angular 2 组件的每个实例生成 id 因为我需要不同的 jquery 每个组件的选择器
这是我的组件
@Component({
selector: 'full-calendar',
templateUrl: 'full-calendar.html'
})
export class FullCalendarComponent {
ngOnChanges(changes: any) {
$('angular2-fullcalendar').fullCalendar('option',changes.options.currentValue)
}
}
我想每次使用多个不同的选择器
我找到了 this 解决方案
export class GetId {
protected getId(id: number|string = _.uniqueId()): string {
return _.lowerFirst(this.constructor.name) + '_' + id;
}
}
class MyComponent extends GetId {
...
}
id可以这样使用
<input [id]="getId('name')" type="text">
但我仍在寻找内置解决方案。
假设你有一个复选框,
<input class="styled-checkbox" id="{{checkboxId}}" type="checkbox">
<label for="{{checkboxId}}">{{checkboxLabel}}</label>
import { Component, Input } from '@angular/core';
@Component({
selector: 'checkbox',
templateUrl: './checkbox.component.html'
})
export class CheckboxComponent {
@Input() checkboxId:string;
@Input() checkboxLabel:string;
}
父级 -->
<checkbox [checkboxId]="Math.random().toString(36).substring(2)"></checkbox>
遍历 DOM:坏主意
您不应该使用 jQuery 遍历 DOM 并对其应用一些转换,原因如下:
Jquery 与 DOM 紧密耦合,而 angular 倾向于抽象所有这些交互:当您修改 angular 中的 DOM 时,您应该使用将对元素应用转换的 Renderer
API。这就是允许在 Worker 上渲染、构建 nativescript 应用程序等的原因。
如果要从父组件遍历 DOM 以应用修改,可能会出现一些问题:
- 某些元素可以通过 Angular 渲染器动态添加到 DOM 或从中删除。如何处理有条件渲染的元素?遍历每个变化检测是一种反模式。
- 当元素已被 angular 渲染器删除时,如何确保您应用在元素上的插件已被正确销毁?
有时候你确实需要jQuery
如果您确实需要使用 jQuery,例如在元素上应用 jQuery 插件,更好的做法是编写指令或组件并通过添加来应用插件模板中的指令或组件而不是从组件遍历 DOM。
您可以像这样创建一个指令:
注意:我对完整的日历没有概念API,所以完全是即兴创作。
@Directive({ selector: '[fullCalendar]' })
export class HighlightDirective implements OnInit,OnDestroy,OnChanges {
private jqElement:any;
constructor(private el: ElementRef) {
el.nativeElement.style.backgroundColor = 'yellow';
}
@Input()
options:any={};
ngOnInit(){
this.jqElement = $(this.el.nativeElement);
this.jqElement.fullCalendar(this.options);
}
ngOnChanges(changes:{[k:string]:SimpleChange}){
if(changes['options']&&!changes['options'].firstChange) // do not apply options on first change (jquery plugin not applied)
this.jqElement.fullCalendar("option",this.options);
}
ngOnDestroy(){
this.jqElement.fullCalendar("destroy");
}
}
并这样应用:
<div fullCalendar [options]="someOptions"></div>
一个简单而优雅的解决方案(找到了here)
let searchBoxId = 0;
@Component({
selector: 'app-auto-complete',
templateUrl: './auto-complete.component.html',
styleUrls: ['./auto-complete.component.less']
})
export class MyComponent implements AfterViewInit {
@Input() searchBoxId = `search-box-${searchBoxId++}`;
ngAfterViewInit(): void {
const searchBox = document.getElementById(`${this.searchBoxId}`);
// Get your input unique id
console.log("searchBox: ")
}
}
- 设置全局变量
- 每次使用(加载)组件时 - 我们计算变量
- 确保您从 DOM 获取唯一 ID,仅在加载后 (ngAfterViewInit)