Skip to content
This repository was archived by the owner on Apr 30, 2018. It is now read-only.

Commit 3b25b1e

Browse files
committed
v8.0.3
2 parents ee6dc72 + cf67c40 commit 3b25b1e

File tree

4 files changed

+147
-49
lines changed

4 files changed

+147
-49
lines changed

dist/formly.js

Lines changed: 142 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*!
2-
* angular-formly JavaScript Library v7.3.9
2+
* angular-formly JavaScript Library v8.0.3
33
*
44
* @license MIT (http://license.angular-formly.com)
55
*
@@ -153,7 +153,7 @@ return /******/ (function(modules) { // webpackBootstrap
153153

154154
ngModule.constant('formlyApiCheck', _providersFormlyApiCheck2['default']);
155155
ngModule.constant('formlyErrorAndWarningsUrlPrefix', _otherDocsBaseUrl2['default']);
156-
ngModule.constant('formlyVersion', ("7.3.9")); // <-- webpack variable
156+
ngModule.constant('formlyVersion', ("8.0.3")); // <-- webpack variable
157157

158158
ngModule.provider('formlyUsability', _providersFormlyUsability2['default']);
159159
ngModule.provider('formlyConfig', _providersFormlyConfig2['default']);
@@ -288,6 +288,12 @@ return /******/ (function(modules) { // webpackBootstrap
288288
message: formlyExpression.optional
289289
}).strict]));
290290

291+
var watcherChecker = apiCheck.typeOrArrayOf(apiCheck.shape({
292+
expression: formlyExpression.optional,
293+
listener: formlyExpression.optional,
294+
runFieldExpressions: apiCheck.bool.optional
295+
}));
296+
291297
var fieldOptionsApiShape = {
292298
$$hashKey: apiCheck.any.optional,
293299
type: apiCheck.shape.ifNot(['template', 'templateUrl'], apiCheck.string).optional,
@@ -314,10 +320,7 @@ return /******/ (function(modules) { // webpackBootstrap
314320
getterSetter: apiCheck.bool.optional,
315321
timezone: apiCheck.string.optional
316322
}).optional,
317-
watcher: apiCheck.typeOrArrayOf(apiCheck.shape({
318-
expression: formlyExpression.optional,
319-
listener: formlyExpression
320-
})).optional,
323+
watcher: watcherChecker.optional,
321324
validators: validatorChecker.optional,
322325
asyncValidators: validatorChecker.optional,
323326
parsers: apiCheck.arrayOf(formlyExpression).optional,
@@ -360,6 +363,8 @@ return /******/ (function(modules) { // webpackBootstrap
360363
updateInitialValue: apiCheck.func.optional,
361364
removeChromeAutoComplete: apiCheck.bool.optional,
362365
templateManipulators: templateManipulators.optional,
366+
manualModelWatcher: apiCheck.oneOfType([apiCheck.bool, apiCheck.func]).optional,
367+
watchAllExpressions: apiCheck.bool.optional,
363368
wrapper: specifyWrapperType.optional,
364369
fieldTransform: apiCheck.oneOfType([apiCheck.func, apiCheck.array]).optional,
365370
data: apiCheck.object.optional
@@ -374,6 +379,7 @@ return /******/ (function(modules) { // webpackBootstrap
374379
options: formOptionsApi.optional,
375380
templateOptions: apiCheck.object.optional,
376381
wrapper: specifyWrapperType.optional,
382+
watcher: watcherChecker.optional,
377383
hide: apiCheck.bool.optional,
378384
hideExpression: formlyExpression.optional,
379385
data: apiCheck.object.optional,
@@ -424,7 +430,7 @@ return /******/ (function(modules) { // webpackBootstrap
424430
Object.defineProperty(exports, "__esModule", {
425431
value: true
426432
});
427-
exports["default"] = "https://github.com/formly-js/angular-formly/blob/" + ("7.3.9") + "/other/ERRORS_AND_WARNINGS.md#";
433+
exports["default"] = "https://github.com/formly-js/angular-formly/blob/" + ("8.0.3") + "/other/ERRORS_AND_WARNINGS.md#";
428434
module.exports = exports["default"];
429435

430436
/***/ },
@@ -1232,7 +1238,7 @@ return /******/ (function(modules) { // webpackBootstrap
12321238

12331239
// @ngInject
12341240
function FormlyFieldController($scope, $timeout, $parse, $controller, formlyValidationMessages) {
1235-
/* eslint max-statements:[2, 32] */
1241+
/* eslint max-statements:[2, 34] */
12361242
if ($scope.options.fieldGroup) {
12371243
setupFieldGroup();
12381244
return;
@@ -1250,6 +1256,7 @@ return /******/ (function(modules) { // webpackBootstrap
12501256
setDefaultValue();
12511257
setInitialValue();
12521258
runExpressions();
1259+
watchExpressions();
12531260
addValidationMessages($scope.options);
12541261
invokeControllers($scope, $scope.options, fieldType);
12551262

@@ -1269,6 +1276,23 @@ return /******/ (function(modules) { // webpackBootstrap
12691276
}, 0, false);
12701277
}
12711278

1279+
function watchExpressions() {
1280+
if ($scope.formOptions.watchAllExpressions) {
1281+
(function () {
1282+
var field = $scope.options;
1283+
var currentValue = valueGetterSetter();
1284+
_angularFix2['default'].forEach(field.expressionProperties, function watchExpression(expression, prop) {
1285+
var setter = $parse(prop).assign;
1286+
$scope.$watch(function expressionPropertyWatcher() {
1287+
return formlyUtil.formlyEval($scope, expression, currentValue, currentValue);
1288+
}, function expressionPropertyListener(value) {
1289+
setter(field, value);
1290+
}, true);
1291+
});
1292+
})();
1293+
}
1294+
}
1295+
12721296
function valueGetterSetter(newVal) {
12731297
if (!$scope.model || !$scope.options.key) {
12741298
return undefined;
@@ -1771,7 +1795,7 @@ return /******/ (function(modules) { // webpackBootstrap
17711795
if (!isUrl) {
17721796
return templatePromise;
17731797
} else {
1774-
var _ret2 = (function () {
1798+
var _ret3 = (function () {
17751799
var httpOptions = { cache: $templateCache };
17761800
return {
17771801
v: templatePromise.then(function (url) {
@@ -1784,7 +1808,7 @@ return /******/ (function(modules) { // webpackBootstrap
17841808
};
17851809
})();
17861810

1787-
if (typeof _ret2 === 'object') return _ret2.v;
1811+
if (typeof _ret3 === 'object') return _ret3.v;
17881812
}
17891813
}
17901814

@@ -2030,7 +2054,7 @@ return /******/ (function(modules) { // webpackBootstrap
20302054
if (attrs.hasOwnProperty('isFieldGroup') && el.parent().parent().hasClass('formly')) {
20312055
parentFormAttributes = copyAttributes(el.parent().parent()[0].attributes);
20322056
}
2033-
return '\n <' + rootEl + ' class="formly"\n name="' + getFormName() + '"\n role="form" ' + parentFormAttributes + '>\n <' + fieldRootEl + ' formly-field\n ng-repeat="field in fields ' + getTrackBy() + '"\n ' + getHideDirective() + '="!field.hide"\n class="formly-field"\n options="field"\n model="field.model || model"\n original-model="model"\n fields="fields"\n form="theFormlyForm"\n form-id="' + getFormName() + '"\n form-state="options.formState"\n form-options="options"\n index="$index">\n </' + fieldRootEl + '>\n <div ng-transclude class="' + getTranscludeClass() + '"></div>\n </' + rootEl + '>\n ';
2057+
return '\n <' + rootEl + ' class="formly"\n name="' + getFormName() + '"\n role="form" ' + parentFormAttributes + '>\n <' + fieldRootEl + ' formly-field\n ng-repeat="field in fields ' + getTrackBy() + '"\n ' + getHideDirective() + '="!field.hide"\n class="formly-field"\n options="field"\n model="field.model"\n original-model="model"\n fields="fields"\n form="theFormlyForm"\n form-id="' + getFormName() + '"\n form-state="options.formState"\n form-options="options"\n index="$index">\n </' + fieldRootEl + '>\n <div ng-transclude class="' + getTranscludeClass() + '"></div>\n </' + rootEl + '>\n ';
20342058

20352059
function getRootEl() {
20362060
return attrs.rootEl || 'ng-form';
@@ -2091,29 +2115,46 @@ return /******/ (function(modules) { // webpackBootstrap
20912115
setupFields();
20922116

20932117
// watch the model and evaluate watch expressions that depend on it.
2094-
$scope.$watch('model', onModelOrFormStateChange, true);
2118+
if (!$scope.options.manualModelWatcher) {
2119+
$scope.$watch('model', onModelOrFormStateChange, true);
2120+
} else if (_angularFix2['default'].isFunction($scope.options.manualModelWatcher)) {
2121+
$scope.$watch($scope.options.manualModelWatcher, onModelOrFormStateChange, true);
2122+
}
2123+
20952124
if ($scope.options.formState) {
20962125
$scope.$watch('options.formState', onModelOrFormStateChange, true);
20972126
}
20982127

20992128
function onModelOrFormStateChange() {
2100-
_angularFix2['default'].forEach($scope.fields, function runFieldExpressionProperties(field, index) {
2101-
var model = field.model || $scope.model;
2102-
var promise = field.runExpressions && field.runExpressions();
2103-
if (field.hideExpression) {
2104-
// can't use hide with expressionProperties reliably
2105-
var val = model[field.key];
2106-
field.hide = evalCloseToFormlyExpression(field.hideExpression, val, field, index);
2107-
}
2108-
if (field.extras && field.extras.validateOnModelChange && field.formControl) {
2109-
var validate = field.formControl.$validate;
2110-
if (promise) {
2111-
promise.then(validate);
2112-
} else {
2113-
validate();
2114-
}
2129+
_angularFix2['default'].forEach($scope.fields, runFieldExpressionProperties);
2130+
}
2131+
2132+
function validateFormControl(formControl, promise) {
2133+
var validate = formControl.$validate;
2134+
if (promise) {
2135+
promise.then(validate);
2136+
} else {
2137+
validate();
2138+
}
2139+
}
2140+
2141+
function runFieldExpressionProperties(field, index) {
2142+
var model = field.model || $scope.model;
2143+
var promise = field.runExpressions && field.runExpressions();
2144+
if (field.hideExpression) {
2145+
// can't use hide with expressionProperties reliably
2146+
var val = model[field.key];
2147+
field.hide = evalCloseToFormlyExpression(field.hideExpression, val, field, index);
2148+
}
2149+
if (field.extras && field.extras.validateOnModelChange && field.formControl) {
2150+
if (_angularFix2['default'].isArray(field.formControl)) {
2151+
_angularFix2['default'].forEach(field.formControl, function (formControl) {
2152+
validateFormControl(formControl, promise);
2153+
});
2154+
} else {
2155+
validateFormControl(field.formControl, promise);
21152156
}
2116-
});
2157+
}
21172158
}
21182159

21192160
function setupFields() {
@@ -2138,6 +2179,10 @@ return /******/ (function(modules) { // webpackBootstrap
21382179

21392180
setupModels();
21402181

2182+
if ($scope.options.watchAllExpressions) {
2183+
_angularFix2['default'].forEach($scope.fields, setupHideExpressionWatcher);
2184+
}
2185+
21412186
_angularFix2['default'].forEach($scope.fields, attachKey); // attaches a key based on the index if a key isn't specified
21422187
_angularFix2['default'].forEach($scope.fields, setupWatchers); // setup watchers for all fields
21432188
}
@@ -2184,6 +2229,8 @@ return /******/ (function(modules) { // webpackBootstrap
21842229
function setupModels() {
21852230
// a set of field models that are already watched (the $scope.model will have its own watcher)
21862231
var watchedModels = [$scope.model];
2232+
// we will not set up automatic model watchers if manual mode is set
2233+
var manualModelWatcher = $scope.options.manualModelWatcher;
21872234

21882235
if ($scope.options.formState) {
21892236
// $scope.options.formState will have its own watcher
@@ -2193,7 +2240,7 @@ return /******/ (function(modules) { // webpackBootstrap
21932240
_angularFix2['default'].forEach($scope.fields, function (field) {
21942241
var isNewModel = initModel(field);
21952242

2196-
if (field.model && isNewModel && watchedModels.indexOf(field.model) === -1) {
2243+
if (field.model && isNewModel && watchedModels.indexOf(field.model) === -1 && !manualModelWatcher) {
21972244
$scope.$watch(function () {
21982245
return field.model;
21992246
}, onModelOrFormStateChange, true);
@@ -2202,24 +2249,56 @@ return /******/ (function(modules) { // webpackBootstrap
22022249
});
22032250
}
22042251

2252+
function setupHideExpressionWatcher(field, index) {
2253+
if (field.hideExpression) {
2254+
(function () {
2255+
// can't use hide with expressionProperties reliably
2256+
var model = field.model || $scope.model;
2257+
$scope.$watch(function hideExpressionWatcher() {
2258+
var val = model[field.key];
2259+
return evalCloseToFormlyExpression(field.hideExpression, val, field, index);
2260+
}, function (hide) {
2261+
return field.hide = hide;
2262+
}, true);
2263+
})();
2264+
}
2265+
}
2266+
22052267
function initModel(field) {
22062268
var isNewModel = true;
22072269

22082270
if (_angularFix2['default'].isString(field.model)) {
2209-
var expression = field.model;
2210-
var index = $scope.fields.indexOf(field);
2271+
(function () {
2272+
var expression = field.model;
2273+
2274+
isNewModel = !referencesCurrentlyWatchedModel(expression);
22112275

2212-
isNewModel = !refrencesCurrentlyWatchedModel(expression);
2276+
field.model = resolveStringModel(expression);
22132277

2214-
field.model = evalCloseToFormlyExpression(expression, undefined, field, index);
2215-
if (!field.model) {
2278+
$scope.$watch(function () {
2279+
return resolveStringModel(expression);
2280+
}, function (model) {
2281+
return field.model = model;
2282+
});
2283+
})();
2284+
} else if (!field.model) {
2285+
field.model = $scope.model;
2286+
}
2287+
return isNewModel;
2288+
2289+
function resolveStringModel(expression) {
2290+
var index = $scope.fields.indexOf(field);
2291+
var model = evalCloseToFormlyExpression(expression, undefined, field, index, { model: $scope.model });
2292+
2293+
if (!model) {
22162294
throw formlyUsability.getFieldError('field-model-must-be-initialized', 'Field model must be initialized. When specifying a model as a string for a field, the result of the' + ' expression must have been initialized ahead of time.', field);
22172295
}
2296+
2297+
return model;
22182298
}
2219-
return isNewModel;
22202299
}
22212300

2222-
function refrencesCurrentlyWatchedModel(expression) {
2301+
function referencesCurrentlyWatchedModel(expression) {
22232302
return ['model', 'formState'].some(function (item) {
22242303
return formlyUtil.startsWith(expression, item + '.') || formlyUtil.startsWith(expression, item + '[');
22252304
});
@@ -2232,15 +2311,15 @@ return /******/ (function(modules) { // webpackBootstrap
22322311
}
22332312

22342313
function setupWatchers(field, index) {
2235-
if (isFieldGroup(field) || !_angularFix2['default'].isDefined(field.watcher)) {
2314+
if (!_angularFix2['default'].isDefined(field.watcher)) {
22362315
return;
22372316
}
22382317
var watchers = field.watcher;
22392318
if (!_angularFix2['default'].isArray(watchers)) {
22402319
watchers = [watchers];
22412320
}
22422321
_angularFix2['default'].forEach(watchers, function setupWatcher(watcher) {
2243-
if (!_angularFix2['default'].isDefined(watcher.listener)) {
2322+
if (!_angularFix2['default'].isDefined(watcher.listener) && !watcher.runFieldExpressions) {
22442323
throw formlyUsability.getFieldError('all-field-watchers-must-have-a-listener', 'All field watchers must have a listener', field);
22452324
}
22462325
var watchExpression = getWatchExpression(watcher, field, index);
@@ -2252,7 +2331,12 @@ return /******/ (function(modules) { // webpackBootstrap
22522331
}
22532332

22542333
function getWatchExpression(watcher, field, index) {
2255-
var watchExpression = watcher.expression || 'model[\'' + field.key.toString().split('.').join('\'][\'') + '\']';
2334+
var watchExpression = undefined;
2335+
if (!_angularFix2['default'].isUndefined(watcher.expression)) {
2336+
watchExpression = watcher.expression;
2337+
} else if (field.key) {
2338+
watchExpression = 'model[\'' + field.key.toString().split('.').join('\'][\'') + '\']';
2339+
}
22562340
if (_angularFix2['default'].isFunction(watchExpression)) {
22572341
(function () {
22582342
// wrap the field's watch expression so we can call it with the field as the first arg
@@ -2264,20 +2348,29 @@ return /******/ (function(modules) { // webpackBootstrap
22642348
};
22652349
watchExpression.displayName = 'Formly Watch Expression for field for ' + field.key;
22662350
})();
2351+
} else if (field.model) {
2352+
watchExpression = $parse(watchExpression).bind(null, $scope, { model: field.model });
22672353
}
22682354
return watchExpression;
22692355
}
22702356

22712357
function getWatchListener(watcher, field, index) {
22722358
var watchListener = watcher.listener;
2273-
if (_angularFix2['default'].isFunction(watchListener)) {
2359+
if (_angularFix2['default'].isFunction(watchListener) || watcher.runFieldExpressions) {
22742360
(function () {
22752361
// wrap the field's watch listener so we can call it with the field as the first arg
22762362
// and the stop function as the last arg as a helper
22772363
var originalListener = watchListener;
22782364
watchListener = function formlyWatchListener() {
2279-
var args = modifyArgs.apply(undefined, [watcher, index].concat(_slice.call(arguments)));
2280-
return originalListener.apply(undefined, _toConsumableArray(args));
2365+
var value = undefined;
2366+
if (originalListener) {
2367+
var args = modifyArgs.apply(undefined, [watcher, index].concat(_slice.call(arguments)));
2368+
value = originalListener.apply(undefined, _toConsumableArray(args));
2369+
}
2370+
if (watcher.runFieldExpressions) {
2371+
runFieldExpressionProperties(field, index);
2372+
}
2373+
return value;
22812374
};
22822375
watchListener.displayName = 'Formly Watch Listener for field for ' + field.key;
22832376
})();
@@ -2294,16 +2387,21 @@ return /******/ (function(modules) { // webpackBootstrap
22942387
}
22952388

22962389
function evalCloseToFormlyExpression(expression, val, field, index) {
2297-
var extraLocals = getFormlyFieldLikeLocals(field, index);
2390+
var extraLocals = arguments.length <= 4 || arguments[4] === undefined ? {} : arguments[4];
2391+
2392+
extraLocals = _angularFix2['default'].extend(getFormlyFieldLikeLocals(field, index), extraLocals);
22982393
return formlyUtil.formlyEval($scope, expression, val, val, extraLocals);
22992394
}
23002395

23012396
function getFormlyFieldLikeLocals(field, index) {
23022397
// this makes it closer to what a regular formlyExpression would be
23032398
return {
2399+
model: field.model,
23042400
options: field,
23052401
index: index,
23062402
formState: $scope.options.formState,
2403+
originalModel: $scope.model,
2404+
formOptions: $scope.options,
23072405
formId: $scope.formId
23082406
};
23092407
}
@@ -2577,7 +2675,7 @@ return /******/ (function(modules) { // webpackBootstrap
25772675
var bothBooleanAndBound = ['required', 'disabled'];
25782676
var bothAttributeAndBound = ['pattern', 'minlength'];
25792677
var statementOnly = ['change', 'keydown', 'keyup', 'keypress', 'click', 'focus', 'blur'];
2580-
var attributeOnly = ['placeholder', 'min', 'max', 'tabindex', 'type'];
2678+
var attributeOnly = ['placeholder', 'min', 'max', 'step', 'tabindex', 'type'];
25812679
if (formlyConfig.extras.ngModelAttrsManipulatorPreferUnbound) {
25822680
bothAttributeAndBound.push('maxlength');
25832681
} else {

dist/formly.min.js

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/formly.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "angular-formly",
3-
"version": "7.3.9",
3+
"version": "8.0.3",
44
"author": "Astrism <[email protected]>",
55
"contributors": [
66
"Astrism <[email protected]>",

0 commit comments

Comments
 (0)