@angular-redux/form
Version:
Build Angular 2+ forms with Redux
1,261 lines (1,244 loc) • 54.1 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('immutable'), require('rxjs/operators'), require('@angular-redux/store'), require('@angular/core'), require('@angular/forms')) :
typeof define === 'function' && define.amd ? define('@angular-redux/form', ['exports', 'immutable', 'rxjs/operators', '@angular-redux/store', '@angular/core', '@angular/forms'], factory) :
(factory((global['angular-redux'] = global['angular-redux'] || {}, global['angular-redux'].form = {}),global.immutable,global.rxjs.operators,global.angularReduxStore,global.ng.core,global.ng.forms));
}(this, (function (exports,immutable,operators,store,core,forms) { 'use strict';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
var composeReducers = function () {
var reducers = [];
for (var _i = 0; _i < arguments.length; _i++) {
reducers[_i] = arguments[_i];
}
return function (s, action) {
return reducers.reduce(function (st, reducer) { return reducer(st, action); }, s);
};
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
var FORM_CHANGED = '@@angular-redux/form/FORM_CHANGED';
var FormStore = /** @class */ (function () {
/// NOTE(cbond): The declaration of store is misleading. This class is
/// actually capable of taking a plain Redux store or an NgRedux instance.
/// But in order to make the ng dependency injector work properly, we
/// declare it as an NgRedux type, since the @angular-redux/store use case involves
/// calling the constructor of this class manually (from configure.ts),
/// where a plain store can be cast to an NgRedux. (For our purposes, they
/// have almost identical shapes.)
function FormStore(store$$1) {
this.store = store$$1;
}
/**
* @return {?}
*/
FormStore.prototype.getState = /**
* @return {?}
*/
function () {
return this.store.getState();
};
/**
* @param {?} fn
* @return {?}
*/
FormStore.prototype.subscribe = /**
* @param {?} fn
* @return {?}
*/
function (fn) {
var _this = this;
return this.store.subscribe(function () { return fn(_this.getState()); });
};
/**
* @template T
* @param {?} path
* @param {?} form
* @param {?} value
* @return {?}
*/
FormStore.prototype.valueChanged = /**
* @template T
* @param {?} path
* @param {?} form
* @param {?} value
* @return {?}
*/
function (path, form, value) {
this.store.dispatch({
type: FORM_CHANGED,
payload: {
path: path,
form: form,
valid: form.valid === true,
value: value,
},
});
};
FormStore.decorators = [
{ type: core.Injectable }
];
/** @nocollapse */
FormStore.ctorParameters = function () {
return [
{ type: store.NgRedux }
];
};
return FormStore;
}());
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b)
if (b.hasOwnProperty(p))
d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign = function () {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s)
if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __values(o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m)
return m.call(o);
return {
next: function () {
if (o && i >= o.length)
o = void 0;
return { value: o && o[i++], done: !o };
}
};
}
function __read(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m)
return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done)
ar.push(r.value);
}
catch (error) {
e = { error: error };
}
finally {
try {
if (r && !r.done && (m = i["return"]))
m.call(i);
}
finally {
if (e)
throw e.error;
}
}
return ar;
}
function __spread() {
for (var ar = [], i = 0; i < arguments.length; i++)
ar = ar.concat(__read(arguments[i]));
return ar;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var FormException = /** @class */ (function (_super) {
__extends(FormException, _super);
function FormException(msg) {
return _super.call(this, msg) || this;
}
return FormException;
}(Error));
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @abstract
*/
var /**
* @abstract
*/ State = /** @class */ (function () {
function State() {
}
/**
* @template StateType
* @param {?} state
* @param {?} path
* @param {?=} fn
* @return {?}
*/
State.traverse = /**
* @template StateType
* @param {?} state
* @param {?} path
* @param {?=} fn
* @return {?}
*/
function (state, path, fn) {
var e_1, _a;
/** @type {?} */
var deepValue = state;
try {
for (var path_1 = __values(path), path_1_1 = path_1.next(); !path_1_1.done; path_1_1 = path_1.next()) {
var k = path_1_1.value;
/** @type {?} */
var parent_1 = deepValue;
if (immutable.isCollection(deepValue)) {
/** @type {?} */
var m = ( /** @type {?} */((( /** @type {?} */(deepValue)))));
if (typeof m.get === 'function') {
deepValue = m.get(k);
}
else {
throw new FormException("Cannot retrieve value from immutable nonassociative container: " + k);
}
}
else if (deepValue instanceof Map) {
deepValue = (( /** @type {?} */((( /** @type {?} */(deepValue)))))).get(k);
}
else {
deepValue = (( /** @type {?} */(deepValue)))[k];
}
if (typeof fn === 'function') {
/** @type {?} */
var transformed = fn(parent_1, k, path.slice(path.indexOf(k) + 1), deepValue);
deepValue = transformed[k];
Object.assign(parent_1, transformed);
}
// If we were not able to find this state inside of our root state
// structure, then we return undefined -- not null -- to indicate that
// state. But this could be a perfectly normal use-case so we don't
// want to throw an exception or anything along those lines.
if (deepValue === undefined) {
return undefined;
}
}
}
catch (e_1_1) {
e_1 = { error: e_1_1 };
}
finally {
try {
if (path_1_1 && !path_1_1.done && (_a = path_1.return))
_a.call(path_1);
}
finally {
if (e_1)
throw e_1.error;
}
}
return deepValue;
};
/**
* @template StateType
* @param {?} state
* @param {?} path
* @return {?}
*/
State.get = /**
* @template StateType
* @param {?} state
* @param {?} path
* @return {?}
*/
function (state, path) {
return State.traverse(state, path);
};
/**
* @template StateType
* @param {?} state
* @param {?} path
* @param {?=} value
* @return {?}
*/
State.assign = /**
* @template StateType
* @param {?} state
* @param {?} path
* @param {?=} value
* @return {?}
*/
function (state, path, value) {
/** @type {?} */
var operations = State.inspect(state);
if (path.length === 0) {
return operations.update(null, value);
}
/** @type {?} */
var root = operations.clone();
// We want to shallow clone the object, and then trace a path to the place
// we want to update, cloning each object we traversed on our way and then
// finally updating the value on the last parent to be @value. This seems
// to offer the best performance: we can shallow clone everything that has
// not been modified, and {deep clone + update} the path down to the value
// that we wish to update.
State.traverse(root, path, function (parent, key, remainingPath, innerValue) {
/** @type {?} */
var parentOperations = State.inspect(parent);
if (innerValue) {
/** @type {?} */
var innerOperations = State.inspect(innerValue);
return parentOperations.update(key, remainingPath.length > 0
? innerOperations.clone()
: innerOperations.merge(null, value));
}
else {
/** @type {?} */
var getProbableType = function (stateKey) {
// NOTE(cbond): If your code gets here, you might not be using the library
/// correctly. If you are assigning into a path in your state, try to
/// ensure that there is a path to traverse, even if everything is just
/// empty objects and arrays. If we have to guess the type of the containers
/// and then create them ourselves, we may not get the types right. Use
/// the Redux `initial state' construct to resolve this issue if you like.
return typeof stateKey === 'number'
? new Array()
: Array.isArray(stateKey)
? immutable.Map()
: new Object();
};
return parentOperations.update(key, remainingPath.length > 0
? getProbableType(remainingPath[0])
: value);
}
});
return root;
};
/**
* @template K
* @param {?} object
* @return {?}
*/
State.inspect = /**
* @template K
* @param {?} object
* @return {?}
*/
function (object) {
/** @type {?} */
var metaOperations = function (
// TODO: Write proper type declarations for following Function types
update, merge, clone) {
/** @type {?} */
var operations = {
/// Clone the object (shallow)
clone: typeof clone === 'function'
? function () { return ( /** @type {?} */(clone(( /** @type {?} */(object))))); }
: function () { return object; },
/// Update a specific key inside of the container object
update: function (key, value) {
return update(operations.clone(), key, value);
},
/// Merge existing values with new values
merge: function (key, value) {
/** @type {?} */
var cloned = operations.clone();
return merge(cloned, key, value, function (v) { return update(cloned, key, v); });
},
};
return operations;
};
if (immutable.isCollection(object)) {
return metaOperations(
// Replace
function (parent, key, value) {
if (key != null) {
return parent.set(key, value);
}
else {
return value;
}
},
// Merge
function (parent, key, value) {
if (key) {
return parent.mergeDeepIn(Array.isArray(key) ? key : [key], value);
}
else {
if (immutable.Map.isMap(value)) {
return parent.mergeDeep(value);
}
else {
return parent.concat(value);
}
}
});
}
else if (Array.isArray(object)) {
return metaOperations(
// Replace array contents
function (parent, key, value) {
if (key != null) {
parent[key] = value;
}
else {
parent.splice.apply(parent, [0, parent.length].concat(Array.isArray(value) ? value : [value]));
}
},
// Merge
function (parent, _, value, setter) {
setter(parent.concat(value));
return parent;
},
// Clone
function () { return Array.prototype.slice.call(object, 0); });
}
else if (object instanceof Map) {
return metaOperations(
// Update map key
function (parent, key, value) {
if (key != null) {
return parent.set(key, value);
}
else {
/** @type {?} */
var m = new Map(( /** @type {?} */(value)));
parent.clear();
m.forEach(function (mapValue, index) { return parent.set(index, mapValue); });
return parent;
}
},
// Merge
function (parent, _, value) {
/** @type {?} */
var m = new Map(( /** @type {?} */(value)));
m.forEach(function (mapValue, key) { return parent.set(key, mapValue); });
return parent;
},
// Clone
function () {
return object instanceof WeakMap
? new WeakMap(( /** @type {?} */(object)))
: new Map(( /** @type {?} */(object)));
});
}
else if (object instanceof WeakSet || object instanceof Set) {
return metaOperations(
// Update element at index in set
function (parent, key, value) {
if (key != null) {
return parent.set(key, value);
}
else {
/** @type {?} */
var s = new Set(( /** @type {?} */(value)));
s.forEach(function (setValue, index) { return parent.set(index, setValue); });
s.clear();
return parent;
}
},
// Merge
function (parent, _, value) {
var e_2, _a;
try {
for (var value_1 = __values(value), value_1_1 = value_1.next(); !value_1_1.done; value_1_1 = value_1.next()) {
var element = value_1_1.value;
parent.add(element);
}
}
catch (e_2_1) {
e_2 = { error: e_2_1 };
}
finally {
try {
if (value_1_1 && !value_1_1.done && (_a = value_1.return))
_a.call(value_1);
}
finally {
if (e_2)
throw e_2.error;
}
}
return parent;
},
// Clone
function () {
return object instanceof WeakSet
? new WeakSet(( /** @type {?} */(object)))
: new Set(( /** @type {?} */(object)));
});
}
else if (object instanceof Date) {
throw new FormException('Cannot understand why a Date object appears in the mutation path!');
}
else {
switch (typeof object) {
case 'boolean':
case 'function':
case 'number':
case 'string':
case 'symbol':
case 'undefined':
break;
case 'object':
if (object == null) {
break;
}
return metaOperations(function (parent, key, value) {
var _a;
if (key != null) {
return __assign({}, parent, (_a = {}, _a[key] = value, _a));
}
return __assign({}, parent, (( /** @type {?} */(value))));
}, function (parent, _, value) {
var e_3, _a;
try {
for (var _b = __values(Object.keys(value)), _c = _b.next(); !_c.done; _c = _b.next()) {
var k = _c.value;
parent[k] = (( /** @type {?} */(value)))[k];
}
}
catch (e_3_1) {
e_3 = { error: e_3_1 };
}
finally {
try {
if (_c && !_c.done && (_a = _b.return))
_a.call(_b);
}
finally {
if (e_3)
throw e_3.error;
}
}
return parent;
}, function () { return (__assign({}, (( /** @type {?} */(object))))); });
default:
break;
}
}
throw new Error("An object of type " + typeof object + " has appeared in the mutation path! Every element " +
'in the mutation path should be an array, an associative container, or a set');
};
/**
* @param {?} value
* @return {?}
*/
State.empty = /**
* @param {?} value
* @return {?}
*/
function (value) {
return (value == null ||
(value.length === 0 ||
(typeof value.length === 'undefined' &&
Object.keys(value).length === 0)));
};
return State;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
var defaultFormReducer = function (initialState) {
/** @type {?} */
var reducer = function (state, action) {
if (state === void 0) {
state = initialState;
}
switch (action.type) {
case FORM_CHANGED:
return State.assign(state, action.payload.path, action.payload.value);
default:
return state;
}
};
return reducer;
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/// Use this function in your providers list if you are not using @angular-redux/core.
/// This will allow you to provide a preexisting store that you have already
/// configured, rather than letting @angular-redux/core create one for you.
/** @type {?} */
var provideReduxForms = function (store$$1) {
/** @type {?} */
var abstractStore = wrap(store$$1);
return [
{ provide: FormStore, useValue: new FormStore(( /** @type {?} */(abstractStore))) },
];
};
/** @type {?} */
var wrap = function (store$$1) {
/** @type {?} */
var dispatch = function (action) { return store$$1.dispatch(action); };
/** @type {?} */
var getState = function () { return ( /** @type {?} */(store$$1.getState())); };
/** @type {?} */
var subscribe = function (fn) {
return store$$1.subscribe(function () { return fn(store$$1.getState()); });
};
return { dispatch: dispatch, getState: getState, subscribe: subscribe };
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var ConnectBase = /** @class */ (function () {
function ConnectBase() {
}
Object.defineProperty(ConnectBase.prototype, "path", {
get: /**
* @return {?}
*/ function () {
/** @type {?} */
var path = typeof this.connect === 'function' ? this.connect() : this.connect;
switch (typeof path) {
case 'object':
if (State.empty(path)) {
return [];
}
if (Array.isArray(path)) {
return ( /** @type {?} */(path));
}
case 'string':
return (( /** @type {?} */(path))).split(/\./g);
default:
// fallthrough above (no break)
throw new Error("Cannot determine path to object: " + JSON.stringify(path));
}
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
ConnectBase.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
if (this.formSubscription) {
this.formSubscription.unsubscribe();
}
if (typeof this.stateSubscription === 'function') {
this.stateSubscription(); // unsubscribe
}
};
/**
* @return {?}
*/
ConnectBase.prototype.ngAfterContentInit = /**
* @return {?}
*/
function () {
var _this = this;
Promise.resolve().then(function () {
_this.resetState();
if (_this.store) {
_this.stateSubscription = _this.store.subscribe(function () { return _this.resetState(); });
}
Promise.resolve().then(function () {
_this.formSubscription = (( /** @type {?} */(_this.form.valueChanges)))
.pipe(operators.debounceTime(0))
.subscribe(function (values) { return _this.publish(values); });
});
});
};
/**
* @private
* @param {?} path
* @param {?} formElement
* @return {?}
*/
ConnectBase.prototype.descendants = /**
* @private
* @param {?} path
* @param {?} formElement
* @return {?}
*/
function (path, formElement) {
var _this = this;
var e_1, _a;
/** @type {?} */
var pairs = new Array();
if (formElement instanceof forms.FormArray) {
formElement.controls.forEach(function (c, index) {
var e_2, _a;
try {
for (var _b = __values(_this.descendants((( /** @type {?} */(path))).concat([index]), c)), _c = _b.next(); !_c.done; _c = _b.next()) {
var d = _c.value;
pairs.push(d);
}
}
catch (e_2_1) {
e_2 = { error: e_2_1 };
}
finally {
try {
if (_c && !_c.done && (_a = _b.return))
_a.call(_b);
}
finally {
if (e_2)
throw e_2.error;
}
}
});
}
else if (formElement instanceof forms.FormGroup) {
try {
for (var _b = __values(Object.keys(formElement.controls)), _c = _b.next(); !_c.done; _c = _b.next()) {
var k = _c.value;
pairs.push({
path: path.concat([k]),
control: formElement.controls[k],
});
}
}
catch (e_1_1) {
e_1 = { error: e_1_1 };
}
finally {
try {
if (_c && !_c.done && (_a = _b.return))
_a.call(_b);
}
finally {
if (e_1)
throw e_1.error;
}
}
}
else if (formElement instanceof forms.NgControl ||
formElement instanceof forms.FormControl) {
return [{ path: path, control: ( /** @type {?} */(formElement)) }];
}
else {
throw new Error("Unknown type of form element: " + formElement.constructor.name);
}
return pairs.filter(function (p) {
/** @type {?} */
var parent = (( /** @type {?} */(p.control)))._parent;
return parent === _this.form.control || parent === _this.form;
});
};
/**
* @private
* @return {?}
*/
ConnectBase.prototype.resetState = /**
* @private
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var formElement = this.form.control === undefined ? this.form : this.form.control;
/** @type {?} */
var children = this.descendants([], formElement);
children.forEach(function (c) {
var path = c.path, control = c.control;
/** @type {?} */
var value = State.get(_this.getState(), _this.path.concat(path));
if (control.value !== value) {
control.setValue(value);
}
});
};
/**
* @private
* @param {?} value
* @return {?}
*/
ConnectBase.prototype.publish = /**
* @private
* @param {?} value
* @return {?}
*/
function (value) {
if (this.store) {
this.store.valueChanged(this.path, this.form, value);
}
};
/**
* @private
* @return {?}
*/
ConnectBase.prototype.getState = /**
* @private
* @return {?}
*/
function () {
if (this.store) {
return this.store.getState();
}
};
ConnectBase.propDecorators = {
connect: [{ type: core.Input }]
};
return ConnectBase;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// For reactive forms (without implicit NgForm)
var ReactiveConnectDirective = /** @class */ (function (_super) {
__extends(ReactiveConnectDirective, _super);
function ReactiveConnectDirective(store$$1) {
var _this = _super.call(this) || this;
_this.store = store$$1;
return _this;
}
ReactiveConnectDirective.decorators = [
{ type: core.Directive, args: [{ selector: 'form[connect][formGroup]' },] }
];
/** @nocollapse */
ReactiveConnectDirective.ctorParameters = function () {
return [
{ type: FormStore }
];
};
ReactiveConnectDirective.propDecorators = {
formGroup: [{ type: core.Input }]
};
return ReactiveConnectDirective;
}(ConnectBase));
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// For template forms (with implicit NgForm)
var ConnectDirective = /** @class */ (function (_super) {
__extends(ConnectDirective, _super);
function ConnectDirective(store$$1, form) {
var _this = _super.call(this) || this;
_this.store = store$$1;
_this.form = form;
return _this;
}
ConnectDirective.decorators = [
{ type: core.Directive, args: [{ selector: 'form[connect]:not([formGroup])' },] }
];
/** @nocollapse */
ConnectDirective.ctorParameters = function () {
return [
{ type: FormStore },
{ type: forms.NgForm }
];
};
return ConnectDirective;
}(ConnectBase));
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
var declarations = [ConnectDirective, ReactiveConnectDirective];
var NgReduxFormConnectModule = /** @class */ (function () {
function NgReduxFormConnectModule() {
}
NgReduxFormConnectModule.decorators = [
{ type: core.NgModule, args: [{
declarations: __spread(declarations),
exports: __spread(declarations),
},] }
];
return NgReduxFormConnectModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var ConnectArrayTemplate = /** @class */ (function () {
function ConnectArrayTemplate($implicit, index, item) {
this.$implicit = $implicit;
this.index = index;
this.item = item;
}
return ConnectArrayTemplate;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @param {?} name
* @param {?} parent
* @return {?}
*/
function controlPath(name, parent) {
return __spread((parent.path || []), [name]);
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var ConnectArrayDirective = /** @class */ (function (_super) {
__extends(ConnectArrayDirective, _super);
function ConnectArrayDirective(parent, rawValidators, rawAsyncValidators, connection, templateRef, viewContainerRef, store$$1) {
var _this = _super.call(this) || this;
_this.parent = parent;
_this.rawValidators = rawValidators;
_this.rawAsyncValidators = rawAsyncValidators;
_this.connection = connection;
_this.templateRef = templateRef;
_this.viewContainerRef = viewContainerRef;
_this.store = store$$1;
_this.array = new forms.FormArray([]);
_this.stateSubscription = _this.store.subscribe(function (state) {
return _this.resetState(state);
});
_this.registerInternals(_this.array);
return _this;
}
Object.defineProperty(ConnectArrayDirective.prototype, "connectArrayOf", {
set: /**
* @param {?} collection
* @return {?}
*/ function (collection) {
this.key = collection;
this.resetState(this.store.getState());
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
ConnectArrayDirective.prototype.ngOnInit = /**
* @return {?}
*/
function () {
this.formDirective.addControl(( /** @type {?} */(this)));
};
Object.defineProperty(ConnectArrayDirective.prototype, "name", {
get: /**
* @return {?}
*/ function () {
return this.key || '';
},
enumerable: true,
configurable: true
});
Object.defineProperty(ConnectArrayDirective.prototype, "control", {
get: /**
* @return {?}
*/ function () {
return this.array;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ConnectArrayDirective.prototype, "formDirective", {
get: /**
* @return {?}
*/ function () {
return ( /** @type {?} */(this.parent.formDirective));
},
enumerable: true,
configurable: true
});
Object.defineProperty(ConnectArrayDirective.prototype, "path", {
get: /**
* @return {?}
*/ function () {
return this.key ? controlPath(this.key, this.parent) : [];
},
enumerable: true,
configurable: true
});
Object.defineProperty(ConnectArrayDirective.prototype, "validator", {
get: /**
* @return {?}
*/ function () {
return forms.Validators.compose(this.rawValidators);
},
enumerable: true,
configurable: true
});
Object.defineProperty(ConnectArrayDirective.prototype, "asyncValidator", {
get: /**
* @return {?}
*/ function () {
return forms.Validators.composeAsync(this.rawAsyncValidators);
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
ConnectArrayDirective.prototype.updateValueAndValidity = /**
* @return {?}
*/
function () {
// stub?
};
/**
* @return {?}
*/
ConnectArrayDirective.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.viewContainerRef.clear();
if (this.key) {
this.formDirective.form.removeControl(this.key);
}
this.stateSubscription();
};
/**
* @private
* @param {?} state
* @return {?}
*/
ConnectArrayDirective.prototype.resetState = /**
* @private
* @param {?} state
* @return {?}
*/
function (state) {
var e_1, _a;
if (this.key == null || this.key.length === 0) {
return; // no state to retreive if no key is set
}
/** @type {?} */
var iterable = State.get(state, this.connection.path.concat(this.path));
/** @type {?} */
var index = 0;
try {
for (var iterable_1 = __values(iterable), iterable_1_1 = iterable_1.next(); !iterable_1_1.done; iterable_1_1 = iterable_1.next()) {
var value = iterable_1_1.value;
/** @type {?} */
var viewRef = this.viewContainerRef.length > index
? (( /** @type {?} */(this.viewContainerRef.get(index))))
: null;
if (viewRef == null) {
/** @type {?} */
var embeddedViewRef = this.viewContainerRef.createEmbeddedView(this.templateRef, new ConnectArrayTemplate(index, index, value), index);
this.patchDescendantControls(embeddedViewRef);
this.array.insert(index, this.transform(this.array, embeddedViewRef.context.item));
}
else {
Object.assign(viewRef.context, new ConnectArrayTemplate(index, index, value));
}
++index;
}
}
catch (e_1_1) {
e_1 = { error: e_1_1 };
}
finally {
try {
if (iterable_1_1 && !iterable_1_1.done && (_a = iterable_1.return))
_a.call(iterable_1);
}
finally {
if (e_1)
throw e_1.error;
}
}
while (this.viewContainerRef.length > index) {
this.viewContainerRef.remove(this.viewContainerRef.length - 1);
}
};
/**
* @private
* @param {?} array
* @return {?}
*/
ConnectArrayDirective.prototype.registerInternals = /**
* @private
* @param {?} array
* @return {?}
*/
function (array) {
array.registerControl = function () { return undefined; };
array.registerOnChange = function () { return undefined; };
Object.defineProperties(this, {
_rawValidators: {
value: this.rawValidators || [],
},
_rawAsyncValidators: {
value: this.rawAsyncValidators || [],
},
});
};
/**
* @private
* @param {?} viewRef
* @return {?}
*/
ConnectArrayDirective.prototype.patchDescendantControls = /**
* @private
* @param {?} viewRef
* @return {?}
*/
function (viewRef) {
var _this = this;
/** @type {?} */
var groups = Object.keys(viewRef._view)
.map(function (k) { return viewRef._view[k]; })
.filter(function (c) { return c instanceof forms.NgModelGroup; });
groups.forEach(function (c) {
Object.defineProperties(c, {
_parent: {
value: _this,
},
_checkParentType: {
value: function () { return undefined; },
},
});
});
};
/**
* @private
* @param {?} parent
* @param {?} reference
* @return {?}
*/
ConnectArrayDirective.prototype.transform = /**
* @private
* @param {?} parent
* @param {?} reference
* @return {?}
*/
function (parent, reference) {
var _this = this;
/** @type {?} */
var emptyControl = function () {
/** @type {?} */
var control = new forms.FormControl(null);
control.setParent(parent);
return control;
};
if (reference == null) {
return emptyControl();
}
if (typeof reference.toJS === 'function') {
reference = reference.toJS();
}
switch (typeof reference) {
case 'string':
case 'number':
case 'boolean':
return emptyControl();
}
/** @type {?} */
var iterate = function (iterable) {
var e_2, _a;
/** @type {?} */
var array = new forms.FormArray([]);
_this.registerInternals(array);
for (var i = array.length; i > 0; i--) {
array.removeAt(i);
}
try {
for (var iterable_2 = __values(iterable), iterable_2_1 = iterable_2.next(); !iterable_2_1.done; iterable_2_1 = iterable_2.next()) {
var value = iterable_2_1.value;
/** @type {?} */
var transformed = _this.transform(array, value);
if (transformed) {
array.push(transformed);
}
}
}
catch (e_2_1) {
e_2 = { error: e_2_1 };
}
finally {
try {
if (iterable_2_1 && !iterable_2_1.done && (_a = iterable_2.return))
_a.call(iterable_2);
}
finally {
if (e_2)
throw e_2.error;
}
}
return array;
};
/** @type {?} */
var associate = function (value) {
var e_3, _a;
/** @type {?} */
var group = new forms.FormGroup({});
group.setParent(parent);
try {
for (var _b = __values(Object.keys(value)), _c = _b.next(); !_c.done; _c = _b.next()) {
var key = _c.value;
/** @type {?} */
var transformed = _this.transform(group, value[key]);
if (transformed) {
group.addControl(key, transformed);
}
}
}
catch (e_3_1) {
e_3 = { error: e_3_1 };
}
finally {
try {
if (_c && !_c.done && (_a = _b.return))
_a.call(_b);
}
finally {
if (e_3)
throw e_3.error;
}
}
return group;
};
if (Array.isArray(reference)) {
return iterate(( /** @type {?} */(reference)));
}
else if (reference instanceof Set) {
return iterate(( /** @type {?} */(reference)));
}
else if (reference instanceof Map) {
return associate(( /** @type {?} */(reference)));
}
else if (reference instanceof Object) {
return associate(reference);
}
else {
throw new Error("Cannot convert object of type " + typeof reference + " / " + reference.toString() + " to form element");
}
};
ConnectArrayDirective.decorators = [
{ type: core.Directive, args: [{
selector: '[connectArray]',
providers: [
{
provide: forms.ControlContainer,
useExisting: core.forwardRef(function () { return ConnectArrayDirective; }),
},
],