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

Commit 54fc0d3

Browse files
author
Kent C. Dodds
committed
Merge pull request #535 from MCKRUZ/master
fix(formly-field): Added fix for nested object properties - issue num…
2 parents f229710 + 785bc6f commit 54fc0d3

File tree

2 files changed

+86
-9
lines changed

2 files changed

+86
-9
lines changed

src/directives/formly-field.js

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,41 @@ function formlyField($http, $q, $compile, $templateCache, $interpolate, formlyCo
7777
return undefined
7878
}
7979
if (angular.isDefined(newVal)) {
80-
$scope.model[$scope.options.key] = newVal
80+
parseSet($scope.options.key, $scope.model, newVal)
81+
}
82+
return parseGet($scope.options.key, $scope.model)
83+
}
84+
85+
function parseSet(key, model, newVal) {
86+
// If either of these are null/undefined then just return undefined
87+
if (!key || !model) {
88+
return
89+
}
90+
// If we are working with a number then $parse wont work, default back to the old way for now
91+
if (angular.isNumber(key)) {
92+
// TODO: Fix this so we can get several levels instead of just one with properties that are numeric
93+
model[key] = newVal
94+
} else {
95+
const setter = $parse($scope.options.key).assign
96+
if (setter) {
97+
setter($scope.model, newVal)
98+
}
99+
}
100+
}
101+
102+
function parseGet(key, model) {
103+
// If either of these are null/undefined then just return undefined
104+
if (!key || !model) {
105+
return undefined
106+
}
107+
108+
// If we are working with a number then $parse wont work, default back to the old way for now
109+
if (angular.isNumber(key)) {
110+
// TODO: Fix this so we can get several levels instead of just one with properties that are numeric
111+
return model[key]
112+
} else {
113+
return $parse(key)(model)
81114
}
82-
return $scope.model[$scope.options.key]
83115
}
84116

85117
function simplifyLife(options) {
@@ -109,14 +141,14 @@ function formlyField($http, $q, $compile, $templateCache, $interpolate, formlyCo
109141
}
110142

111143
function setDefaultValue() {
112-
if (angular.isDefined($scope.options.defaultValue) && !angular.isDefined($scope.model[$scope.options.key])) {
113-
const setter = $parse($scope.options.key).assign
114-
setter($scope.model, $scope.options.defaultValue)
144+
if (angular.isDefined($scope.options.defaultValue) &&
145+
!angular.isDefined(parseGet($scope.options.key, $scope.model))) {
146+
parseSet($scope.options.key, $scope.model, $scope.options.defaultValue)
115147
}
116148
}
117149

118150
function setInitialValue() {
119-
$scope.options.initialValue = $scope.model && $scope.model[$scope.options.key]
151+
$scope.options.initialValue = $scope.model && parseGet($scope.options.key, $scope.model)
120152
}
121153

122154
function mergeFieldOptionsWithTypeDefaults(options, type) {
@@ -151,7 +183,7 @@ function formlyField($http, $q, $compile, $templateCache, $interpolate, formlyCo
151183
}
152184

153185
function resetModel() {
154-
$scope.model[$scope.options.key] = $scope.options.initialValue
186+
parseSet($scope.options.key, $scope.model, $scope.options.initialValue)
155187
if ($scope.options.formControl) {
156188
if (angular.isArray($scope.options.formControl)) {
157189
angular.forEach($scope.options.formControl, function(formControl) {
@@ -165,7 +197,7 @@ function formlyField($http, $q, $compile, $templateCache, $interpolate, formlyCo
165197

166198
function resetFormControl(formControl, isMultiNgModel) {
167199
if (!isMultiNgModel) {
168-
formControl.$setViewValue($scope.model[$scope.options.key])
200+
formControl.$setViewValue(parseGet($scope.options.key, $scope.model))
169201
}
170202

171203
formControl.$render()
@@ -179,7 +211,7 @@ function formlyField($http, $q, $compile, $templateCache, $interpolate, formlyCo
179211
}
180212

181213
function updateInitialValue() {
182-
$scope.options.initialValue = $scope.model[$scope.options.key]
214+
$scope.options.initialValue = parseGet($scope.options.key, $scope.model)
183215
}
184216

185217
function addValidationMessages(options) {

src/directives/formly-field.test.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,6 +1240,51 @@ describe('formly-field', function() {
12401240
expect(field.formControl.$dirty).to.be.false
12411241
})
12421242

1243+
it(`should reset the form state with a deep model`, () => {
1244+
const field = getNewField({key: 'foo.bar'})
1245+
scope.fields = [field]
1246+
compileAndDigest()
1247+
1248+
// initial state
1249+
expect(field.formControl.$dirty).to.be.false
1250+
expect(field.formControl.$touched).to.be.false
1251+
1252+
// modification
1253+
scope.model.foo = {
1254+
bar: '~=[,,_,,]:3',
1255+
}
1256+
field.formControl.$setTouched()
1257+
field.formControl.$setDirty()
1258+
scope.$digest()
1259+
1260+
// expect modification
1261+
expect(field.formControl.$dirty).to.be.true
1262+
expect(field.formControl.$touched).to.be.true
1263+
expect(field.formControl.$modelValue).to.eq('~=[,,_,,]:3')
1264+
1265+
// Set new initialValue
1266+
scope.options.updateInitialValue()
1267+
1268+
// Modify again
1269+
scope.model.foo.bar = 'l33t'
1270+
field.formControl.$setTouched()
1271+
field.formControl.$setDirty()
1272+
scope.$digest()
1273+
1274+
// expect modification
1275+
expect(field.formControl.$dirty).to.be.true
1276+
expect(field.formControl.$touched).to.be.true
1277+
expect(field.formControl.$modelValue).to.eq('l33t')
1278+
1279+
// reset state
1280+
scope.options.resetModel()
1281+
1282+
// expect reset
1283+
expect(field.formControl.$modelValue).to.eq('~=[,,_,,]:3')
1284+
expect(field.formControl.$touched).to.be.false
1285+
expect(field.formControl.$dirty).to.be.false
1286+
})
1287+
12431288
it(`should reset the form state for an field with multiple ng-models`, () => {
12441289
const field = {
12451290
key: 'multiNgModel',

0 commit comments

Comments
 (0)