Javascript 停止使用DefaultIterableDiffer、KeyValueDiffers工厂或IterableDiffers工厂
-我正在尝试从角度2升级到角度5 -我按照下面链接中的说明操作 -我正在尝试执行此步骤-停止使用IterableDiffers#工厂 -我不确定我应该用什么来代替它。 -现在我已经对这些行进行了注释并运行了应用程序……其他组件工作正常。 -下面提供我的代码片段Javascript 停止使用DefaultIterableDiffer、KeyValueDiffers工厂或IterableDiffers工厂,javascript,html,angularjs,angular2-routing,angular5,Javascript,Html,Angularjs,Angular2 Routing,Angular5,-我正在尝试从角度2升级到角度5 -我按照下面链接中的说明操作 -我正在尝试执行此步骤-停止使用IterableDiffers#工厂 -我不确定我应该用什么来代替它。 -现在我已经对这些行进行了注释并运行了应用程序……其他组件工作正常。 -下面提供我的代码片段 /* * Angular 2 Dropdown Sports for Bootstrap * Current version: 0.2.0 * * Simon Lindh * https://github.com/softsi
/*
* 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 { }
/*
*Angular 2下拉式运动鞋,用于引导
*当前版本:0.2.0
*
*西蒙·林德
* https://github.com/softsimon/angular-2-dropdown-Sports
*/
从“@angular/core”导入{NgModule,Component,Pipe,OnInit,DoCheck,HostListener,Input,ElementRef,Output,EventEmitter,forwardRef};
//从“@angular/core”导入{NgModule,Component,Pipe,OnInit,DoCheck,HostListener,Input,ElementRef,Output,EventEmitter,forwardRef,IterableDiffers};
从“@angular/common”导入{CommonModule};
从'rxjs/Rx'导入{Observable};
从“@angular/forms”导入{FormsModule,NG_VALUE_ACCESSOR,ControlValueAccessor};
从“../../services/saveService”导入{saveService};
常量值存取器:任意={
提供:NG_值访问器,
useExisting:forwardRef(()=>SportsDropdown),
多:真的
};
导出接口端口选项{
id:编号;
名称:字符串;
}
导出接口ISportsSettings{
pullRight?:布尔值;
启用搜索?:布尔值;
checkedStyle?:“复选框”|“字形图标”;
buttonClasses?:字符串;
selectionLimit?:数字;
closeOnSelect?:布尔值;
showCheckAll?:布尔值;
showUncheckAll?:布尔值;
DynamicTimeMaxItems?:编号;
maxHeight?:字符串;
isAll?:布尔型;
}
导出接口ISportsTexts{
checkAll?:字符串;
uncheckAll?:字符串;
选中?:字符串;
选中复数?:字符串;
搜索占位符?:字符串;
defaultTitle?:字符串;
}
@烟斗({
名称:'searchFilter'
})
导出类搜索筛选器{
转换(选项:数组,参数:字符串):数组{
返回options.filter((option:ISportsOption)=>option.name.toLowerCase().indexOf((args | |“”).toLowerCase())>-1);
}
}
@组成部分({
选择器:“ss Sports下拉列表”,
提供者:[体育价值存取者],
风格:[`
{大纲:无!重要;}
`],
模板:`
{{title}}
-
-
-
`
})
导出类Sports下拉列表实现OnInit、DoCheck、ControlValueAccessor{
@Input()选项:数组;
@Input()设置:iPortsSettings;
@Input()文本:ISportsTexts;
@Output()selectionlimitreach=neweventemitter();
@Output()modelChangeDetected=新的EventEmitter();
@HostListener('文档:单击',['$event.target']))
onClick(目标){
让parentFound=false;
while(target!==null&&!parentFound){
if(target==this.element.nativeElement){
parentFound=true;
}
target=target.parentElement;
}
如果(!parentFound){
this.isVisible=false;
}
}
受保护的onModelChange:Function=(\ux:any)=>{};
受保护的onModelTouched:Function=()=>{};
受保护型号:编号[];
保护标题:字符串;
//保护区:任何;
已选择受保护的数值:数值=0;
受保护的isVisible:布尔值=false;
受保护的searchFilterText:string='';
受保护的默认设置:ISportsSettings={
普鲁特:错,
启用搜索:false,
checkedStyle:“复选框”,
按钮分类:“btn btn默认值”,
selectionLimit:0,
closeOnSelect:false,
showCheckAll:false,
肖恩切卡尔:错,
DynamicTimeMaxItems:1,
最大高度:“300px”,
伊索尔:是的
};
受保护的默认文本:ISportsTexts={
checkAll:'全部',
取消选中:“全部取消选中”,
选中:“选中”,
checked复数:“checked”,
searchPlaceholder:“搜索…”,
defaultTitle:“选择”,
};
//建造师(
//受保护元素:ElementRef,
//受保护的不同:IterableDiffers,
//公共存储服务:存储服务
// ) {
//this.difference=differences.find([]).create(null);
// }
建造师(
受保护元素:ElementRef,
公共存储服务:存储服务
) {
//this.difference=differences.find([]).create(null);
}
恩戈尼尼特(){
this.settings=Object.assign(this.defaultSettings,this.settings);
this.text=Object.assign(this.defaulttext,this.text);
}
writeValue(值:任意):无效{
如果(值!==未定义){
该模型=值;
}
}
注册表更改(fn:功能):无效{
this.onModelChange=fn;
}
寄存器(fn:功能):无效{
this.onModelTouched=fn;
}
//ngDoCheck(){
//让更改=this.different.di