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

Commit 89284af

Browse files
Merge pull request #653 from kwypchlo/feature/update-model-reference-for-fields-with-nested-string-model
fix(models): update field model reference for fields with nested string models
2 parents 6cd15e1 + 716f526 commit 89284af

File tree

2 files changed

+34
-9
lines changed

2 files changed

+34
-9
lines changed

src/directives/formly-form.js

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -271,24 +271,31 @@ function formlyForm(formlyUsability, formlyWarn, $parse, formlyConfig, $interpol
271271

272272
if (angular.isString(field.model)) {
273273
const expression = field.model
274-
const index = $scope.fields.indexOf(field)
275274

276275
isNewModel = !referencesCurrentlyWatchedModel(expression)
277276

278-
// temporary assign $scope.model as field.model to evaluate the expression in correct context
277+
field.model = resolveStringModel(expression)
278+
279+
$scope.$watch(() => resolveStringModel(expression), (model) => field.model = model)
280+
} else if (!field.model) {
279281
field.model = $scope.model
280-
field.model = evalCloseToFormlyExpression(expression, undefined, field, index)
281-
if (!field.model) {
282+
}
283+
return isNewModel
284+
285+
function resolveStringModel(expression) {
286+
const index = $scope.fields.indexOf(field)
287+
const model = evalCloseToFormlyExpression(expression, undefined, field, index, {model: $scope.model})
288+
289+
if (!model) {
282290
throw formlyUsability.getFieldError(
283291
'field-model-must-be-initialized',
284292
'Field model must be initialized. When specifying a model as a string for a field, the result of the' +
285293
' expression must have been initialized ahead of time.',
286294
field)
287295
}
288-
} else if (!field.model) {
289-
field.model = $scope.model
296+
297+
return model
290298
}
291-
return isNewModel
292299
}
293300

294301
function referencesCurrentlyWatchedModel(expression) {
@@ -374,8 +381,8 @@ function formlyForm(formlyUsability, formlyWarn, $parse, formlyConfig, $interpol
374381
return [$scope.fields[index], ...originalArgs, watcher.stopWatching]
375382
}
376383

377-
function evalCloseToFormlyExpression(expression, val, field, index) {
378-
const extraLocals = getFormlyFieldLikeLocals(field, index)
384+
function evalCloseToFormlyExpression(expression, val, field, index, extraLocals = {}) {
385+
extraLocals = angular.extend(getFormlyFieldLikeLocals(field, index), extraLocals)
379386
return formlyUtil.formlyEval($scope, expression, val, val, extraLocals)
380387
}
381388

src/directives/formly-form.test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,24 @@ describe('formly-form', () => {
495495
testFormStateAccessor('formState["nested"]')
496496
})
497497

498+
it('should be updated when the reference to the outer model changes', () => {
499+
scope.model.nested.foo = 'bar'
500+
scope.fields[0].model = 'model.nested'
501+
502+
compileAndDigest()
503+
$timeout.flush()
504+
505+
scope.model = {
506+
nested: {
507+
foo: 'baz',
508+
},
509+
}
510+
511+
scope.$digest()
512+
513+
expect(scope.fields[0].model.foo).to.equal('baz')
514+
})
515+
498516
function testModelAccessor(accessor) {
499517
scope.fields[0].model = accessor
500518

0 commit comments

Comments
 (0)