mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 04:14:21 +08:00
fix(): ensure that bindings fore core are being loaded.
This commit is contained in:
124
src/bindings/angular/components/boolean-input.ts
Normal file
124
src/bindings/angular/components/boolean-input.ts
Normal file
@ -0,0 +1,124 @@
|
||||
import { Directive, ElementRef, EventEmitter, HostListener, Input, Output } from '@angular/core';
|
||||
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
@Directive({
|
||||
selector: 'ion-toggle',
|
||||
providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: BooleanInput, multi: true }],
|
||||
})
|
||||
export class BooleanInput {
|
||||
id: string;
|
||||
_labelId: string;
|
||||
_chg: Function;
|
||||
_tch: Function;
|
||||
_dis: Function;
|
||||
|
||||
@Output() ionChange: EventEmitter<any> = new EventEmitter<any>();
|
||||
@Output() ionFocus: EventEmitter<any> = new EventEmitter<any>();
|
||||
@Output() ionBlur: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
|
||||
constructor(public _el: ElementRef) {}
|
||||
|
||||
/**
|
||||
* @input {boolean} If true, the element is selected.
|
||||
*/
|
||||
@Input()
|
||||
get checked(): boolean {
|
||||
return this._el.nativeElement.checked;
|
||||
}
|
||||
set checked(val: boolean) {
|
||||
this._el.nativeElement.checked = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @input {boolean} If true, the user cannot interact with this element.
|
||||
*/
|
||||
@Input()
|
||||
get disabled(): boolean {
|
||||
return this._el.nativeElement.disabled;
|
||||
}
|
||||
set disabled(val: boolean) {
|
||||
this._el.nativeElement.disabled = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @input {string}
|
||||
*/
|
||||
@Input()
|
||||
get value(): string {
|
||||
return this._el.nativeElement.value;
|
||||
}
|
||||
set value(val: string) {
|
||||
this._el.nativeElement.value = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
@HostListener('$ionChange', ['$event'])
|
||||
_onChange(ev: any) {
|
||||
ev.stopPropagation();
|
||||
this._chg && this._chg(ev.detail.checked);
|
||||
this._tch && this._tch();
|
||||
this.ionChange.emit(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
@HostListener('$ionFocus', ['$event'])
|
||||
_onFocus(ev: any) {
|
||||
ev.stopPropagation();
|
||||
this.ionFocus.emit(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
@HostListener('$ionBlur', ['$event'])
|
||||
_onBlur(ev: any) {
|
||||
ev.stopPropagation();
|
||||
this.ionBlur.emit(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
writeValue(val: any) {
|
||||
if (this.checked !== val) {
|
||||
this.checked = val;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
registerOnChange(fn: any) {
|
||||
this._chg = fn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
registerOnTouched(fn: any) {
|
||||
this._tch = fn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
registerOnDisabledChange(fn: any) {
|
||||
this._dis = fn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
setDisabledState(isDisabled: boolean) {
|
||||
this.disabled = isDisabled;
|
||||
}
|
||||
}
|
122
src/bindings/angular/providers/ionic-core.ts
Normal file
122
src/bindings/angular/providers/ionic-core.ts
Normal file
@ -0,0 +1,122 @@
|
||||
import { Config } from '../../../config/config';
|
||||
import { DomController } from '../../../platform/dom-controller';
|
||||
import { NgZone } from '@angular/core';
|
||||
import { Platform } from '../../../platform/platform';
|
||||
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
export function setupCore(config: Config, plt: Platform, domCtrl: DomController, zone: NgZone) {
|
||||
return function() {
|
||||
const win: any = plt.win();
|
||||
const doc = plt.doc();
|
||||
|
||||
const ionic: any = win['Ionic'];
|
||||
|
||||
if (!ionic || !ionic['staticDir']) {
|
||||
// window.Ionic should already exist and
|
||||
// window.Ionic.staticDir should have been added to the
|
||||
// main bundle referencing the static www build directory
|
||||
return;
|
||||
}
|
||||
|
||||
// same controllers are used by ionic core
|
||||
ionic['ConfigCtrl'] = config;
|
||||
|
||||
// keep core and angular dom reads/writes *nsync
|
||||
ionic['DomCtrl'] = domCtrl;
|
||||
|
||||
// next tick controller created here so that it can
|
||||
// be created to run outside of angular
|
||||
ionic['QueueCtrl'] = getQueueController(win, zone);
|
||||
|
||||
// keep core and angular dom reads/writes *nsync
|
||||
ionic['eventNameFn'] = function(eventName: string) {
|
||||
return '$' + eventName;
|
||||
};
|
||||
|
||||
// build up a path for the exact ionic core javascript file this browser needs
|
||||
var pathItems: string[] = ['core'];
|
||||
|
||||
if (!('attachShadow' in Element.prototype)) {
|
||||
// browser requires the shadow dom polyfill
|
||||
pathItems.push('sd');
|
||||
}
|
||||
|
||||
if (!win.customElements) {
|
||||
// browser requires the custom elements polyfill
|
||||
pathItems.push('ce');
|
||||
}
|
||||
|
||||
// request the ionic core file this browser needs
|
||||
var s = doc.createElement('script');
|
||||
s.src = `${ionic['staticDir']}ionic.${pathItems.join('.')}.js`;
|
||||
doc.head.appendChild(s);
|
||||
|
||||
return {};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function getQueueController(win: any, zone: NgZone) {
|
||||
const hostScheduleDefer: Function = win['requestIdleCallback'];
|
||||
const callbacks: Function[] = [];
|
||||
let pending = false;
|
||||
|
||||
function doWork(deadlineObj: any) {
|
||||
// let's see if we've got time to take care of things
|
||||
while (deadlineObj.timeRemaining() > 1 && callbacks.length > 0) {
|
||||
// do some work while within the allowed time
|
||||
// shift the array and fire off the callbacks from the beginning
|
||||
// once we run out of time or callbacks we'll stop
|
||||
callbacks.shift()();
|
||||
}
|
||||
|
||||
// check to see if we still have work to do
|
||||
if (pending = (callbacks.length > 0)) {
|
||||
// everyone just settle down now
|
||||
// we already don't have time to do anything in this callback
|
||||
// let's throw the next one in a requestAnimationFrame
|
||||
// so we can just simmer down for a bit
|
||||
zone.runOutsideAngular(() => {
|
||||
requestAnimationFrame(flush);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function flush() {
|
||||
// always force a bunch of callbacks to run, but still have
|
||||
// a throttle on how many can run in a certain time
|
||||
const start = performance.now();
|
||||
while (callbacks.length > 0 && (performance.now() - start < 4)) {
|
||||
callbacks.shift()();
|
||||
}
|
||||
|
||||
if (pending = (callbacks.length > 0)) {
|
||||
// still more to do yet, but we've run out of time
|
||||
// let's let thing cool off and try again after a raf
|
||||
zone.runOutsideAngular(() => {
|
||||
hostScheduleDefer(doWork);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function add(cb: Function) {
|
||||
// add the work to the end of the callbacks
|
||||
callbacks.push(cb);
|
||||
|
||||
if (!pending) {
|
||||
// not already pending work to do, so let's tee it up
|
||||
pending = true;
|
||||
zone.runOutsideAngular(() => {
|
||||
hostScheduleDefer(doWork);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
add: add,
|
||||
flush: flush
|
||||
};
|
||||
}
|
@ -122,6 +122,7 @@ export { NavController } from './navigation/nav-controller';
|
||||
export { NavControllerBase } from './navigation/nav-controller-base';
|
||||
export { NavParams } from './navigation/nav-params';
|
||||
export { NavLink, NavOptions, DeepLinkConfig, DeepLinkMetadata, DeepLinkMetadataFactory } from './navigation/nav-util';
|
||||
export { setupCore } from './bindings/angular/providers/ionic-core';
|
||||
export { TapClick, setupTapClick, isActivatable } from './tap-click/tap-click';
|
||||
export { UrlSerializer, DeepLinkConfigToken } from './navigation/url-serializer';
|
||||
export { ViewController } from './navigation/view-controller';
|
||||
|
@ -31,6 +31,7 @@ import { ModuleLoader, provideModuleLoader, setupPreloading, LAZY_LOADED_TOKEN }
|
||||
import { NgModuleLoader } from './util/ng-module-loader';
|
||||
import { Platform, setupPlatform } from './platform/platform';
|
||||
import { PlatformConfigToken, providePlatformConfigs } from './platform/platform-registry';
|
||||
import { setupCore } from './bindings/angular/providers/ionic-core';
|
||||
import { TapClick, setupTapClick } from './tap-click/tap-click';
|
||||
import { registerModeConfigs } from './config/mode-registry';
|
||||
import { TransitionController } from './transitions/transition-controller';
|
||||
@ -395,6 +396,7 @@ export class IonicModule {
|
||||
|
||||
// useFactory: ionic app initializers
|
||||
{ provide: APP_INITIALIZER, useFactory: registerModeConfigs, deps: [ Config ], multi: true },
|
||||
{ provide: APP_INITIALIZER, useFactory: setupCore, deps: [ Config, Platform, DomController, NgZone ], multi: true },
|
||||
{ provide: APP_INITIALIZER, useFactory: setupProvideEvents, deps: [ Platform, DomController ], multi: true },
|
||||
{ provide: APP_INITIALIZER, useFactory: setupTapClick, deps: [ Config, Platform, DomController, App, GestureController ], multi: true },
|
||||
{ provide: APP_INITIALIZER, useFactory: setupPreloading, deps: [ Config, DeepLinkConfigToken, ModuleLoader, NgZone ], multi: true },
|
||||
|
Reference in New Issue
Block a user