- 我正在尝试从角度2到角度5进行角度升级 - 我按照以下链接中的说明操作 https://angular-update-guide.firebaseapp.com/ - 我正在尝试执行此步骤停止使用IterableDiffers#factories - 不确定我应该替换IterableDiffe。 - 现在我已经对这些行进行了评论并运行了应用程序......其他组件工作正常。 - 在下面提供我的代码片段。
/*
* Angular 2 Dropdown Sports for Bootstrap
* Current version: 0.2.0
*
* Simon Lindh
* https://github.com/softsimon/angular-2-dropdown-Sports
*/
import { NgModule, Component, Pipe, OnInit, DoCheck, HostListener, Input, ElementRef, Output, EventEmitter, forwardRef } from '@angular/core';
//import { NgModule, Component, Pipe, OnInit, DoCheck, HostListener, Input, ElementRef, Output, EventEmitter, forwardRef, IterableDiffers } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Observable } from 'rxjs/Rx';
import { FormsModule, NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
import {saveService} from '../../services/saveService';
const Sports_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => SportsDropdown),
multi: true
};
export interface ISportsOption {
id: number;
name: string;
}
export interface ISportsSettings {
pullRight?: boolean;
enableSearch?: boolean;
checkedStyle?: 'checkboxes' | 'glyphicon';
buttonClasses?: string;
selectionLimit?: number;
closeOnSelect?: boolean;
showCheckAll?: boolean;
showUncheckAll?: boolean;
dynamicTitleMaxItems?: number;
maxHeight?: string;
isAll?: boolean;
}
export interface ISportsTexts {
checkAll?: string;
uncheckAll?: string;
checked?: string;
checkedPlural?: string;
searchPlaceholder?: string;
defaultTitle?: string;
}
@Pipe({
name: 'searchFilter'
})
export class SportsSearchFilter {
transform(options: Array<ISportsOption>, args: string): Array<ISportsOption> {
return options.filter((option: ISportsOption) => option.name.toLowerCase().indexOf((args || '').toLowerCase()) > -1);
}
}
@Component({
selector: 'ss-Sports-dropdown',
providers: [Sports_VALUE_ACCESSOR],
styles: [`
a { outline: none !important; }
`],
template: `
<div class="btn-group">
<button type="button" style="overflow: auto; overflow-x: hidden; width: 350px;" class="dropdown-toggle" [ngClass]="settings.buttonClasses" (click)="toggleDropdown()">{{ title }} <span class="caret"></span></button>
<ul *ngIf="isVisible" class="dropdown-menu" [class.pull-right]="settings.pullRight" [style.max-height]="settings.maxHeight" style="display: block; height: auto; overflow-y: auto;">
<li style="margin: 0px 5px 5px 5px;" *ngIf="settings.enableSearch">
<div class="input-group input-group-sm">
<span class="input-group-addon" id="sizing-addon3"><i class="fa fa-search"></i></span>
<input type="text" class="form-control" placeholder="{{ texts.searchPlaceholder }}" aria-describedby="sizing-addon3" [(ngModel)]="searchFilterText">
<span class="input-group-btn" *ngIf="searchFilterText.length > 0">
<button class="btn btn-default" type="button" (click)="clearSearch()"><i class="fa fa-times"></i></button>
</span>
</div>
</li>
<li class="divider" *ngIf="settings.enableSearch"></li>
<li *ngIf="!isAllSelected() && settings.isAll">
<a href="javascript:;" role="menuitem" tabindex="-1" (click)="checkAll()">
{{ texts.checkAll }}
</a>
</li>
<li *ngIf="isAllSelected() && settings.isAll">
<a href="javascript:;" role="menuitem" tabindex="-1" (click)="uncheckAll()">
<span style="width: 16px;" class="glyphicon" [class.glyphicon-ok]="isAllSelected()"></span>
{{ texts.checkAll }}
</a>
</li>
<li *ngIf="(settings.showCheckAll || settings.showUncheckAll) && settings.isAll" class="divider"></li>
<li *ngFor="let option of options | searchFilter:searchFilterText">
<a href="javascript:;" role="menuitem" tabindex="-1" (click)="setSelected($event, option)">
<input *ngIf="settings.checkedStyle == 'checkboxes'" type="checkbox" [checked]="isSelected(option)" />
<span *ngIf="settings.checkedStyle == 'glyphicon'" style="width: 16px;" class="glyphicon" [class.glyphicon-ok]="isSelected(option)"></span>
{{ option.name }}
</a>
</li>
</ul>
</div>
`
})
export class SportsDropdown implements OnInit, DoCheck, ControlValueAccessor {
@Input() options: Array<ISportsOption>;
@Input() settings: ISportsSettings;
@Input() texts: ISportsTexts;
@Output() selectionLimitReached = new EventEmitter();
@Output() modelChangeDetected = new EventEmitter();
@HostListener('document: click', ['$event.target'])
onClick(target) {
let parentFound = false;
while (target !== null && !parentFound) {
if (target === this.element.nativeElement) {
parentFound = true;
}
target = target.parentElement;
}
if (!parentFound) {
this.isVisible = false;
}
}
protected onModelChange: Function = (_: any) => {};
protected onModelTouched: Function = () => {};
protected model: number[];
protected title: string;
//protected differ: any;
protected numSelected: number = 0;
protected isVisible: boolean = false;
protected searchFilterText: string = '';
protected defaultSettings: ISportsSettings = {
pullRight: false,
enableSearch: false,
checkedStyle: 'checkboxes',
buttonClasses: 'btn btn-default',
selectionLimit: 0,
closeOnSelect: false,
showCheckAll: false,
showUncheckAll: false,
dynamicTitleMaxItems: 1,
maxHeight: '300px',
isAll: true
};
protected defaultTexts: ISportsTexts = {
checkAll: 'All',
uncheckAll: 'Uncheck all',
checked: 'checked',
checkedPlural: 'checked',
searchPlaceholder: 'Search...',
defaultTitle: 'Select',
};
// constructor(
// protected element: ElementRef,
// protected differs: IterableDiffers,
// public saveService: saveService
// ) {
// this.differ = differs.find([]).create(null);
// }
constructor(
protected element: ElementRef,
public saveService: saveService
) {
// this.differ = differs.find([]).create(null);
}
ngOnInit() {
this.settings = Object.assign(this.defaultSettings, this.settings);
this.texts = Object.assign(this.defaultTexts, this.texts);
}
writeValue(value: any) : void {
if (value !== undefined) {
this.model = value;
}
}
registerOnChange(fn: Function): void {
this.onModelChange = fn;
}
registerOnTouched(fn: Function): void {
this.onModelTouched = fn;
}
// ngDoCheck() {
// let changes = this.differ.diff(this.model);
// if (changes) {
// this.updateNumSelected();
// if(this.options && this.options.length > 0 && this.options[0]["countryName"]) {
// this.updateTitle(true);
// }
// else{
// this.updateTitle(false);
// }
// }
// }
clearSearch() {
this.searchFilterText = '';
}
toggleDropdown() {
this.isVisible = !this.isVisible;
}
isSelected(option: ISportsOption): boolean {
return this.model && this.model.indexOf(option.id) > -1;
}
isAllSelected(): boolean {
if(this.model.length == this.options.length){
return true;
}
else {
return false;
}
}
setSelected(event: Event, option: ISportsOption) {
if(option["countryName"]){
if(this.model.length == 3 && this.model.indexOf(option.id) == -1) {
this.selectionLimitReached.emit(this.model.length);
return;
}
else {
let saveBtnEnable = {};
saveBtnEnable["enableBtn"] = true;
this.saveService.setSaveBtnEnable(saveBtnEnable);
}
}
var index = this.model.indexOf(option.id);
if (index > -1) {
this.model.splice(index, 1);
} else {
if (this.settings.selectionLimit === 0 || this.model.length < this.settings.selectionLimit) {
this.model.push(option.id);
} else {
this.selectionLimitReached.emit(this.model.length);
return;
}
}
if (this.settings.closeOnSelect) {
this.toggleDropdown();
}
this.onModelChange(this.model);
this.modelChangeDetected.emit(true);
}
updateNumSelected() {
this.numSelected = this.model && this.model.length || 0;
}
updateTitle(replaceTitleBySelectedOption : boolean) {
if (this.numSelected === 0) {
this.title = this.texts.defaultTitle;
} else if (this.settings.dynamicTitleMaxItems >= this.numSelected) {
if(replaceTitleBySelectedOption) {
if(this.model.indexOf(213) != -1) {
this.model = [];
this.model.push(213);
}
}
this.title = this.options
.filter((option: ISportsOption) => this.model && this.model.indexOf(option.id) > -1)
.map((option: ISportsOption) => option.name)
.join(', ');
} else {
this.title = this.numSelected + ' ' + (this.numSelected === 1 ? this.texts.checked : this.texts.checkedPlural);
}
}
checkAll() {
this.model = this.options.map(option => option.id);
this.onModelChange(this.model);
}
uncheckAll() {
this.model = [];
this.onModelChange(this.model);
}
}
@NgModule({
imports: [CommonModule, FormsModule],
exports: [SportsDropdown,SportsSearchFilter],
declarations: [SportsDropdown, SportsSearchFilter],
})
export class SportsDropdownModule { }