You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2016/10/03 18:21:45 UTC
[03/18] ambari git commit: AMBARI-18308. Ambari UI: Memory leak while
adding and removing property. (jaimin)
AMBARI-18308. Ambari UI: Memory leak while adding and removing property. (jaimin)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/d8cd374b
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/d8cd374b
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/d8cd374b
Branch: refs/heads/branch-feature-AMBARI-18456
Commit: d8cd374baa7afca9cdb9e682a28ac1563870baa6
Parents: b8e3c10
Author: Jaimin Jetly <ja...@hortonworks.com>
Authored: Thu Sep 29 12:08:23 2016 -0700
Committer: Jaimin Jetly <ja...@hortonworks.com>
Committed: Thu Sep 29 13:02:39 2016 -0700
----------------------------------------------------------------------
.../configs/service_configs_by_category_view.js | 535 +++++++++++--------
.../service_configs_by_category_view_test.js | 7 +-
2 files changed, 311 insertions(+), 231 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/d8cd374b/ambari-web/app/views/common/configs/service_configs_by_category_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/configs/service_configs_by_category_view.js b/ambari-web/app/views/common/configs/service_configs_by_category_view.js
index 579348a..3eebfea 100644
--- a/ambari-web/app/views/common/configs/service_configs_by_category_view.js
+++ b/ambari-web/app/views/common/configs/service_configs_by_category_view.js
@@ -52,27 +52,102 @@ App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, App.ConfigOverri
* and sorted by <code>displayType</code> and <code>index</code>
* @type {App.ServiceConfigProperty[]}
*/
- categoryConfigs: function () {
- // sort content type configs, sort the rest of configs based on index and then add content array at the end (as intended)
- var categoryConfigs = this.get('categoryConfigsAll'),
- contentOrderedArray = this.orderContentAtLast(categoryConfigs.filterProperty('displayType','content')),
- contentFreeConfigs = categoryConfigs.filter(function(config) {return config.get('displayType')!=='content';}),
- indexOrdered = this.sortByIndex(contentFreeConfigs);
-
- return indexOrdered.concat(contentOrderedArray).filterProperty('isVisible', true);
- }.property('categoryConfigsAll.@each.isVisible').cacheable(),
+ categoryConfigs: [],
/**
- * This method provides all the properties which apply
+ * This is array of all the properties which apply
* to this category, irrespective of visibility. This
* is helpful in Oozie/Hive database configuration, where
* MySQL etc. database options don't show up, because
* they were not visible initially.
* @type {App.ServiceConfigProperty[]}
*/
- categoryConfigsAll: function () {
- return this.get('serviceConfigs').filterProperty('category', this.get('category.name'));
- }.property('serviceConfigs.@each').cacheable(),
+ categoryConfigsAll: [],
+
+ didInsertElement: function () {
+ var self = this;
+ this.setCategoryConfigs();
+ this.setVisibleCategoryConfigs();
+ var isCollapsed = this.calcIsCollapsed();
+ this.set('category.isCollapsed', isCollapsed);
+ if (isCollapsed) {
+ this.$('.accordion-body').hide();
+ }
+ else {
+ this.$('.accordion-body').show();
+ }
+ $('#serviceConfig').tooltip({
+ selector: '[data-toggle=tooltip]',
+ placement: 'top'
+ });
+ this.filteredCategoryConfigs();
+ Em.run.next(function () {
+ self.updateReadOnlyFlags();
+ });
+ },
+
+ willDestroyElement: function () {
+ $('[data-toggle=tooltip]').tooltip('destroy');
+ },
+
+ setVisibleCategoryConfigsOnce: function () {
+ Em.run.once(this, 'addConfigToCategoryConfigs');
+ }.observes('categoryConfigsAll.@each.isVisible'),
+
+ setCategoryConfigs: function () {
+ var categoryConfigsAll = this.get('serviceConfigs').filterProperty('category', this.get('category.name'));
+ if (categoryConfigsAll && categoryConfigsAll.length) {
+ this.set('categoryConfigsAll',categoryConfigsAll);
+ }
+ },
+
+ setVisibleCategoryConfigs: function () {
+ var orderedCategoryConfigs = this.getOrderedCategoryConfigs();
+ this.set('categoryConfigs', orderedCategoryConfigs);
+ },
+
+ /**
+ * This method is invoked when any change in visibility of items of `categoryConfigsAll` array happens and accordingly sets `categoryConfigs` array
+ * Instead of completely resetting `categoryConfigs` array whenever this function is invoked , items are added/removed in `categoryConfigs` (which is binded in template)
+ * Doing so is observed to avoid memory leak
+ */
+ addConfigToCategoryConfigs: function () {
+ var orderedCategoryConfigs = this.getOrderedCategoryConfigs();
+ var categoryConfigs = this.get('categoryConfigs');
+ var configsToAdd = [];
+ var configsToRemove = [];
+ // If property is added or made visible then add it to visible categoryconfigs
+ orderedCategoryConfigs.forEach(function(item){
+ var isPresent = categoryConfigs.filterProperty('name', item.get('name')).findProperty('filename',item.get('filename'));
+ if (!isPresent) {
+ configsToAdd.pushObject(item);
+ }
+ }, this);
+
+ // If property is removed or made invisible, then remove it from visible categoryconfigs
+ categoryConfigs.forEach(function(item){
+ var orderedCategoryConfig = orderedCategoryConfigs.filterProperty('name', item.get('name')).findProperty('filename',item.get('filename'));
+ if (!orderedCategoryConfig) {
+ configsToRemove.pushObject(item);
+ }
+ }, this);
+
+ categoryConfigs.pushObjects(configsToAdd);
+ categoryConfigs.removeObjects(configsToRemove);
+ },
+
+ getOrderedCategoryConfigs: function() {
+ var categoryConfigsAll = this.get('categoryConfigsAll');
+ var orderedCategoryConfigs = [];
+ if (categoryConfigsAll) {
+ var contentOrderedArray = this.orderContentAtLast(categoryConfigsAll.filterProperty('displayType','content')),
+ contentFreeConfigs = categoryConfigsAll.filter(function(config) {return config.get('displayType')!=='content';}),
+ indexOrdered = this.sortByIndex(contentFreeConfigs);
+ orderedCategoryConfigs = indexOrdered.concat(contentOrderedArray).filterProperty('isVisible', true);
+ }
+ return orderedCategoryConfigs;
+ },
+
/**
* If added/removed a serverConfigObject, this property got updated.
@@ -304,30 +379,6 @@ App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, App.ConfigOverri
return Em.isNone(this.get('category.isCollapsed')) ? (this.get('category.name').indexOf('Advanced') != -1 || this.get('category.name').indexOf('CapacityScheduler') != -1 || this.get('category.name').indexOf('Custom') != -1) : this.get('category.isCollapsed');
},
- didInsertElement: function () {
- var isCollapsed = this.calcIsCollapsed();
- var self = this;
- this.set('category.isCollapsed', isCollapsed);
- if (isCollapsed) {
- this.$('.accordion-body').hide();
- }
- else {
- this.$('.accordion-body').show();
- }
- $('#serviceConfig').tooltip({
- selector: '[data-toggle=tooltip]',
- placement: 'top'
- });
- this.filteredCategoryConfigs();
- Em.run.next(function () {
- self.updateReadOnlyFlags();
- });
- },
-
- willDestroyElement: function () {
- $('[data-toggle=tooltip]').tooltip('destroy');
- },
-
/**
* @returns {string}
*/
@@ -360,224 +411,243 @@ App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, App.ConfigOverri
isNotSaved: true
}, selectedConfigGroup);
}
- this.get('serviceConfigs').pushObject(App.ServiceConfigProperty.create(config));
+ var serviceConfigProperty = App.ServiceConfigProperty.create(config);
+ this.get('serviceConfigs').pushObject(serviceConfigProperty);
+ this.get('categoryConfigsAll').pushObject(serviceConfigProperty);
},
/**
- * Show popup for adding new config-properties
- * @method showAddPropertyWindow
- */
- showAddPropertyWindow: function () {
- var persistController = this;
- var modePersistKey = this.persistKey();
- var selectedConfigGroup = this.get('controller.selectedConfigGroup');
-
- persistController.getUserPref(modePersistKey).pipe(function (data) {
- return !!data;
- },function () {
- return false;
- }).always((function (isBulkMode) {
-
- var category = this.get('category');
- var siteFileName = category.get('siteFileName');
-
- var service = this.get('service');
- var serviceName = service.get('serviceName');
-
- var configsOfFile = service.get('configs').filterProperty('filename', siteFileName);
-
- /**
- * Find duplications within the same confType
- * Result in error, as no duplicated property keys are allowed in the same configType
- * */
- function isDuplicatedConfigKey(name) {
- return configsOfFile.findProperty('name', name);
- }
+ * Find duplications within the same confType
+ * Result in error, as no duplicated property keys are allowed in the same configType
+ * */
+ isDuplicatedConfigKey: function(name) {
+ var category = this.get('category');
+ var siteFileName = category.get('siteFileName');
+
+ var service = this.get('service');
+ var serviceName = service.get('serviceName');
+
+ var configsOfFile = service.get('configs').filterProperty('filename', siteFileName);
+ return configsOfFile.findProperty('name', name);
+ },
- /**
- * find duplications in all confTypes of the service
- * Result in warning, to remind user the existence of a same-named property
- * */
- function isDuplicatedConfigKeyinConfigs(name) {
- var files = [];
- var configFiles = service.get('configs').mapProperty('filename').uniq();
- configFiles.forEach(function(configFile){
- var configsOfFile = service.get('configs').filterProperty('filename', configFile);
- if(configsOfFile.findProperty('name', name)){
- files.push(configFile);
- }
- }, this);
- return files;
- }
+ /**
+ * find duplications in all confTypes of the service
+ * Result in warning, to remind user the existence of a same-named property
+ * */
+ isDuplicatedConfigKeyinConfigs: function(name) {
+ var files = [];
+ var service = this.get('service');
+ var configFiles = service.get('configs').mapProperty('filename').uniq();
+ configFiles.forEach(function (configFile) {
+ var configsOfFile = service.get('configs').filterProperty('filename', configFile);
+ if (configsOfFile.findProperty('name', name)) {
+ files.push(configFile);
+ }
+ }, this);
+ return files;
+ },
- var serviceConfigObj = Ember.Object.create({
- isBulkMode: isBulkMode,
- bulkConfigValue: '',
- bulkConfigError: false,
- bulkConfigErrorMessage: '',
-
- name: '',
- value: '',
- propertyType: [],
- content: ['PASSWORD', 'USER', 'GROUP', 'TEXT', 'ADDITIONAL_USER_PROPERTY', 'NOT_MANAGED_HDFS_PATH', 'VALUE_FROM_PROPERTY_FILE'],
- isKeyError: false,
- showFilterLink: false,
- errorMessage: '',
- observeAddPropertyValue: function () {
- var name = this.get('name');
- if (name.trim() != '') {
- if (validator.isValidConfigKey(name)) {
- if (!isDuplicatedConfigKey(name)) { //no duplication within the same confType
- var files = isDuplicatedConfigKeyinConfigs(name);
- if (files.length > 0) {
- //still check for a warning, if there are duplications across confTypes
- this.set('showFilterLink', true);
- this.set('isKeyWarning', true);
- this.set('isKeyError', false);
- this.set('warningMessage', Em.I18n.t('services.service.config.addPropertyWindow.error.derivedKey.location').format(files.join(" ")));
- } else {
- this.set('showFilterLink', false);
- this.set('isKeyError', false);
- this.set('isKeyWarning', false);
- this.set('errorMessage', '');
- }
- } else {
- this.set('showFilterLink', true);
- this.set('isKeyError', true);
- this.set('isKeyWarning', false);
- this.set('errorMessage', Em.I18n.t('services.service.config.addPropertyWindow.error.derivedKey.infile'));
- }
+ processAddPropertyWindow: function(isBulkMode, modePersistKey) {
+ var self = this;
+ var category = this.get('category');
+ var siteFileName = category.get('siteFileName');
+
+ var service = this.get('service');
+ var serviceName = service.get('serviceName');
+
+ var serviceConfigObj = Em.Object.create({
+ isBulkMode: isBulkMode,
+ bulkConfigValue: '',
+ bulkConfigError: false,
+ bulkConfigErrorMessage: '',
+
+ name: '',
+ value: '',
+ isKeyError: false,
+ showFilterLink: false,
+ errorMessage: '',
+ observeAddPropertyValue: function () {
+ var name = this.get('name');
+ if (name.trim() != '') {
+ if (validator.isValidConfigKey(name)) {
+ if (!self.isDuplicatedConfigKey(name)) { //no duplication within the same confType
+ var files = self.isDuplicatedConfigKeyinConfigs(name);
+ if (files.length > 0) {
+ //still check for a warning, if there are duplications across confTypes
+ this.set('showFilterLink', true);
+ this.set('isKeyWarning', true);
+ this.set('isKeyError', false);
+ this.set('warningMessage', Em.I18n.t('services.service.config.addPropertyWindow.error.derivedKey.location').format(files.join(" ")));
} else {
this.set('showFilterLink', false);
- this.set('isKeyError', true);
+ this.set('isKeyError', false);
this.set('isKeyWarning', false);
- this.set('errorMessage', Em.I18n.t('form.validator.configKey'));
+ this.set('errorMessage', '');
}
} else {
- this.set('showFilterLink', false);
+ this.set('showFilterLink', true);
this.set('isKeyError', true);
this.set('isKeyWarning', false);
- this.set('errorMessage', Em.I18n.t('services.service.config.addPropertyWindow.error.required'));
+ this.set('errorMessage', Em.I18n.t('services.service.config.addPropertyWindow.error.derivedKey.infile'));
}
- }.observes('name')
- });
-
- function processConfig(config, callback) {
- var lines = config.split('\n');
- var errorMessages = [];
- var parsedConfig = {};
- var propertyCount = 0;
-
- function lineNumber(index) {
- return Em.I18n.t('services.service.config.addPropertyWindow.error.lineNumber').format(index + 1);
+ } else {
+ this.set('showFilterLink', false);
+ this.set('isKeyError', true);
+ this.set('isKeyWarning', false);
+ this.set('errorMessage', Em.I18n.t('form.validator.configKey'));
}
+ } else {
+ this.set('showFilterLink', false);
+ this.set('isKeyError', true);
+ this.set('isKeyWarning', false);
+ this.set('errorMessage', Em.I18n.t('services.service.config.addPropertyWindow.error.required'));
+ }
+ }
+ });
- lines.forEach(function (line, index) {
- if (line.trim() === '') {
- return;
- }
- var delimiter = '=';
- var delimiterPosition = line.indexOf(delimiter);
- if (delimiterPosition === -1) {
- errorMessages.push(lineNumber(index) + Em.I18n.t('services.service.config.addPropertyWindow.error.format'));
- return;
- }
- var key = Em.Handlebars.Utils.escapeExpression(line.slice(0, delimiterPosition).trim());
- var value = line.slice(delimiterPosition + 1);
- if (validator.isValidConfigKey(key)) {
- if (!isDuplicatedConfigKey(key) && !(key in parsedConfig)) {
- parsedConfig[key] = value;
- propertyCount++;
- } else {
- errorMessages.push(lineNumber(index) + Em.I18n.t('services.service.config.addPropertyWindow.error.derivedKey.specific').format(key));
- }
+ App.ModalPopup.show({
+ classNames: ['sixty-percent-width-modal'],
+ header: Em.I18n.t('installer.step7.config.addProperty'),
+ primary: Em.I18n.t('add'),
+ secondary: Em.I18n.t('common.cancel'),
+ onPrimary: function () {
+ var propertyObj = {
+ filename: siteFileName,
+ serviceName: serviceName,
+ categoryName: category.get('name')
+ };
+ if (serviceConfigObj.isBulkMode) {
+ var popup = this;
+ this.processConfig(serviceConfigObj.bulkConfigValue, function (error, parsedConfig) {
+ if (error) {
+ serviceConfigObj.set('bulkConfigError', true);
+ serviceConfigObj.set('bulkConfigErrorMessage', error);
} else {
- errorMessages.push(lineNumber(index) + Em.I18n.t('form.validator.configKey.specific').format(key));
+ for (var key in parsedConfig) {
+ if (parsedConfig.hasOwnProperty(key)) {
+ propertyObj.name = key;
+ propertyObj.value = parsedConfig[key];
+ self.createProperty(propertyObj);
+ }
+ }
+ popup.hide();
}
});
-
- if (errorMessages.length > 0) {
- callback(errorMessages.join('<br>'), parsedConfig);
+ } else {
+ serviceConfigObj.observeAddPropertyValue();
+ /**
+ * For the first entrance use this if (serviceConfigObj.name.trim() != '')
+ */
+ if (!serviceConfigObj.isKeyError) {
+ propertyObj.name = serviceConfigObj.get('name');
+ propertyObj.value = serviceConfigObj.get('value');
+ self.createProperty(propertyObj);
+ this.hide();
}
- else if (propertyCount === 0) {
- callback(Em.I18n.t('services.service.config.addPropertyWindow.propertiesPlaceholder', parsedConfig));
+ }
+ },
+
+ lineNumber: function(index) {
+ return Em.I18n.t('services.service.config.addPropertyWindow.error.lineNumber').format(index + 1);
+ },
+
+ processConfig: function(config, callback) {
+ var lines = config.split('\n');
+ var errorMessages = [];
+ var parsedConfig = {};
+ var propertyCount = 0;
+ lines.forEach(function (line, index) {
+ if (line.trim() === '') {
+ return;
}
- else {
- callback(null, parsedConfig);
+ var delimiter = '=';
+ var delimiterPosition = line.indexOf(delimiter);
+ if (delimiterPosition === -1) {
+ errorMessages.push(this.lineNumber(index) + Em.I18n.t('services.service.config.addPropertyWindow.error.format'));
+ return;
}
- }
-
- App.ModalPopup.show({
- classNames: ['sixty-percent-width-modal'],
- header: Em.I18n.t('installer.step7.config.addProperty'),
- primary: Em.I18n.t('add'),
- secondary: Em.I18n.t('common.cancel'),
- onPrimary: function () {
- var propertyObj = {
- filename: siteFileName,
- serviceName: serviceName,
- categoryName: category.get('name')
- };
- if (serviceConfigObj.isBulkMode) {
- var popup = this;
- processConfig(serviceConfigObj.bulkConfigValue, function (error, parsedConfig) {
- if (error) {
- serviceConfigObj.set('bulkConfigError', true);
- serviceConfigObj.set('bulkConfigErrorMessage', error);
- } else {
- for (var key in parsedConfig) {
- if (parsedConfig.hasOwnProperty(key)) {
- propertyObj.name = key;
- propertyObj.value = parsedConfig[key];
- persistController.createProperty(propertyObj);
- }
- }
- popup.hide();
- }
- });
- }
- else {
- serviceConfigObj.observeAddPropertyValue();
- /**
- * For the first entrance use this if (serviceConfigObj.name.trim() != '')
- */
- if (!serviceConfigObj.isKeyError) {
- propertyObj.name = serviceConfigObj.get('name');
- propertyObj.value = serviceConfigObj.get('value');
- propertyObj.propertyType = serviceConfigObj.get('propertyType');
- persistController.createProperty(propertyObj);
- this.hide();
- }
- }
- },
- bodyClass: Em.View.extend({
- fileName: siteFileName,
- notMisc: serviceName !== 'MISC',
- templateName: require('templates/common/configs/addPropertyWindow'),
- controllerBinding: 'App.router.mainServiceInfoConfigsController',
- serviceConfigObj: serviceConfigObj,
- didInsertElement: function () {
- App.tooltip(this.$("[data-toggle=tooltip]"), {
- placement: "top"
- });
- },
- toggleBulkMode: function () {
- this.toggleProperty('serviceConfigObj.isBulkMode');
- persistController.postUserPref(modePersistKey, this.get('serviceConfigObj.isBulkMode'));
- },
- filterByKey: function (event) {
- var controller = (App.router.get('currentState.name') == 'configs')
- ? App.router.get('mainServiceInfoConfigsController')
- : App.router.get('wizardStep7Controller');
- this.get('parentView').onClose();
- controller.set('filter', event.view.get('serviceConfigObj.name'));
+ var key = Em.Handlebars.Utils.escapeExpression(line.slice(0, delimiterPosition).trim());
+ var value = line.slice(delimiterPosition + 1);
+ if (validator.isValidConfigKey(key)) {
+ if (!self.isDuplicatedConfigKey(key) && !(key in parsedConfig)) {
+ parsedConfig[key] = value;
+ propertyCount++;
+ } else {
+ errorMessages.push(this.lineNumber(index) + Em.I18n.t('services.service.config.addPropertyWindow.error.derivedKey.specific').format(key));
}
- })
+ } else {
+ errorMessages.push(this.lineNumber(index) + Em.I18n.t('form.validator.configKey.specific').format(key));
+ }
});
- }).bind(this));
+ if (errorMessages.length > 0) {
+ callback(errorMessages.join('<br>'), parsedConfig);
+ }
+ else if (propertyCount === 0) {
+ callback(Em.I18n.t('services.service.config.addPropertyWindow.propertiesPlaceholder', parsedConfig));
+ }
+ else {
+ callback(null, parsedConfig);
+ }
+ },
+ willDestroyElement: function () {
+ serviceConfigObj.destroy();
+ this._super();
+ },
+ bodyClass: Em.View.extend({
+ fileName: siteFileName,
+ notMisc: serviceName !== 'MISC',
+ templateName: require('templates/common/configs/addPropertyWindow'),
+ serviceConfigObj: serviceConfigObj,
+ didInsertElement: function () {
+ this._super();
+ serviceConfigObj.addObserver('name', serviceConfigObj, 'observeAddPropertyValue');
+ App.tooltip(this.$("[data-toggle=tooltip]"), {
+ placement: "top"
+ });
+ },
+ willDestroyElement: function () {
+ this.$().popover('destroy');
+ serviceConfigObj.removeObserver('name', serviceConfigObj, 'observeAddPropertyValue');
+ this.set('serviceConfigObj', null);
+ this._super();
+ },
+ toggleBulkMode: function () {
+ this.toggleProperty('serviceConfigObj.isBulkMode');
+ self.postUserPref(modePersistKey, this.get('serviceConfigObj.isBulkMode'));
+ },
+ filterByKey: function (event) {
+ var controller = (App.router.get('currentState.name') == 'configs')
+ ? App.router.get('mainServiceInfoConfigsController')
+ : App.router.get('wizardStep7Controller');
+ this.get('parentView').onClose();
+ controller.set('filter', event.view.get('serviceConfigObj.name'));
+ }
+ })
+ });
+ },
+
+ /**
+ * Show popup for adding new config-properties
+ * @method showAddPropertyWindow
+ */
+ showAddPropertyWindow: function () {
+ var persistController = this;
+ var modePersistKey = this.persistKey();
+ var selectedConfigGroup = this.get('controller.selectedConfigGroup');
+
+ persistController.getUserPref(modePersistKey).then(function (data) {
+ return !!data;
+ },function () {
+ return false;
+ }).always((function (isBulkMode) {
+ persistController.processAddPropertyWindow(isBulkMode, modePersistKey);
+ }));
},
+
+
/**
* Toggle <code>isFinal</code> for selected config-property if <code>isNotEditable</code> is false
* @param {object} event
@@ -589,6 +659,7 @@ App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, App.ConfigOverri
return;
}
serviceConfigProperty.toggleProperty('isFinal');
+ serviceConfigProperty = null;
},
/**
@@ -598,7 +669,6 @@ App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, App.ConfigOverri
*/
removeProperty: function (event) {
var serviceConfigProperty = event.contexts[0];
- this.get('serviceConfigs').removeObject(serviceConfigProperty);
// push config's file name if this config was stored on server
if (!serviceConfigProperty.get('isNotSaved')) {
var modifiedFileNames = this.get('controller.modifiedFileNames'),
@@ -614,6 +684,9 @@ App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, App.ConfigOverri
}
}
}
+ this.get('serviceConfigs').removeObject(serviceConfigProperty);
+ this.get('categoryConfigsAll').removeObject(serviceConfigProperty);
+ serviceConfigProperty = null;
Em.$('body>.tooltip').remove(); //some tooltips get frozen when their owner's DOM element is removed
},
@@ -625,6 +698,7 @@ App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, App.ConfigOverri
setRecommendedValue: function (event) {
var serviceConfigProperty = event.contexts[0];
serviceConfigProperty.set('value', serviceConfigProperty.get('recommendedValue'));
+ serviceConfigProperty = null;
},
/**
@@ -649,6 +723,7 @@ App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, App.ConfigOverri
serviceConfigProperty.set('isFinal', savedIsFinal);
}
this.configChangeObserver(serviceConfigProperty);
+ serviceConfigProperty = null;
Em.$('body>.tooltip').remove(); //some tooltips get frozen when their owner's DOM element is removed
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d8cd374b/ambari-web/test/views/common/configs/service_configs_by_category_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/common/configs/service_configs_by_category_view_test.js b/ambari-web/test/views/common/configs/service_configs_by_category_view_test.js
index 7b6c451..9b49653 100644
--- a/ambari-web/test/views/common/configs/service_configs_by_category_view_test.js
+++ b/ambari-web/test/views/common/configs/service_configs_by_category_view_test.js
@@ -308,9 +308,14 @@ describe('App.ServiceConfigsByCategoryView', function () {
category: {
name: item.categoryNname
},
- serviceConfigs: item.serviceConfigs
+ serviceConfigs: item.serviceConfigs,
+ filteredCategoryConfigs: Em.K,
+ collapseCategory: Em.K
});
+ view.setCategoryConfigs();
+ view.setVisibleCategoryConfigs();
expect(view.get('categoryConfigs').mapProperty('resultId')).to.deep.equal(result);
+ view.destroy();
});
});
});