jQuery的每个组件实例的Angular 2唯一ID

时间:2017-05-03 07:07:10

标签: jquery angular uniqueidentifier angular-components

我有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">

但我仍在寻找内置解决方案。

3 个答案:

答案 0 :(得分:3)

遍历DOM:坏主意

您不应该使用jQuery遍历DOM并对其应用一些转换,原因如下:

Jquery与DOM紧密耦合,而angular倾向于抽象所有这些交互:当您以角度修改DOM时,您应该使用将在元素上应用转换的Renderer API。这允许在Workers上呈现,构建nativescript应用程序等等。

如果要从父组件遍历DOM以应用修改,可能会出现一些问题:

  • Angular渲染器可以动态地向DOM添加或删除某些元素。如何处理有条件渲染的元素?遍历每个变化检测是一种反模式。
  • 当角度渲染器移除元素时,如何确保您在元素上应用的插件已正确销毁?

有时你确实需要jQuery

如果你确实需要使用jQuery,例如在一个元素上应用jQuery插件,那么编写一个指令或一个组件并通过在模板中添加指令或组件来应用插件是一种更好的做法,而不是遍历来自组件的DOM。

您可以创建如下指令:

NB:我不知道完整的日历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>

答案 1 :(得分:2)

假设您有一个复选框

<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;
}
父母中的

- &gt;

<checkbox [checkboxId]="Math.random().toString(36).substring(2)"></checkbox>

答案 2 :(得分:1)

一个简单而优雅的解决方案(找到了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之后,才从DOM中获得唯一ID( ngAfterViewInit