Remove RenderModel

- Use server side converters for model cleanup
This commit is contained in:
Kevin Giszewski
2014-04-29 12:31:02 -04:00
parent 3b5cff8d9a
commit d13a5b1b86
5 changed files with 54 additions and 124 deletions
@@ -22,7 +22,6 @@ namespace Archetype.Umbraco.Extensions
_app = ApplicationContext.Current;
}
internal Models.Archetype DeserializeJsonToArchetype(string sourceJson, PreValueCollection dataTypePreValues)
{
try
@@ -44,8 +43,7 @@ namespace Archetype.Umbraco.Extensions
catch
{
return new Models.Archetype();
}
}
}
internal Models.Archetype DeserializeJsonToArchetype(string sourceJson, int dataTypeId)
@@ -44,6 +44,5 @@ namespace Archetype.Umbraco.PropertyConverters
return archetype;
}
}
}
@@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Archetype.Umbraco.Extensions;
using ClientDependency.Core;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Editors;
@@ -53,7 +55,7 @@ namespace Archetype.Umbraco.PropertyEditors
public override string ConvertDbToString(Property property, PropertyType propertyType, IDataTypeService dataTypeService)
{
if (property.Value == null)
if (property.Value == null || property.Value.ToString() == "")
return string.Empty;
var archetype = new ArchetypeHelper().DeserializeJsonToArchetype(property.Value.ToString(), propertyType.DataTypeDefinitionId);
@@ -70,17 +72,23 @@ namespace Archetype.Umbraco.PropertyEditors
}
}
property.Value = JsonConvert.SerializeObject(archetype);
var json = JObject.Parse(JsonConvert.SerializeObject(archetype));
var propertiesToRemove = new String[] { "propertyEditorAlias", "dataTypeId", "dataTypeGuid" };
return base.ConvertDbToString(property, propertyType, dataTypeService);
json.Descendants().OfType<JProperty>()
.Where(p => propertiesToRemove.Contains(p.Name))
.ToList()
.ForEach(x => x.Remove());
return json.ToString();
}
public override object ConvertDbToEditor(Property property, PropertyType propertyType, IDataTypeService dataTypeService)
{
if (property.Value == null)
if (property.Value == null || property.Value.ToString() == "")
return string.Empty;
var archetype = JsonConvert.DeserializeObject<Models.Archetype>(property.Value.ToString(), _jsonSettings);
var archetype = JsonConvert.DeserializeObject<Models.Archetype>(property.Value.ToString(), _jsonSettings);
foreach (var fieldset in archetype.Fieldsets)
{
@@ -98,7 +106,7 @@ namespace Archetype.Umbraco.PropertyEditors
}
public override object ConvertEditorToDb(ContentPropertyData editorValue, object currentValue)
{
if (editorValue.Value == null)
if (editorValue.Value == null || editorValue.Value.ToString() == "")
return string.Empty;
var archetype = new ArchetypeHelper().DeserializeJsonToArchetype(editorValue.Value.ToString(), editorValue.PreValues);
@@ -115,7 +123,7 @@ namespace Archetype.Umbraco.PropertyEditors
}
}
return JsonConvert.SerializeObject(archetype);
return JsonConvert.SerializeObject(archetype);
}
}
+33 -103
View File
@@ -11,14 +11,11 @@
//ini the model
$scope.model.value = $scope.model.value || getDefaultModel($scope.model.config);
//ini the render model
$scope.archetypeRenderModel = {};
initArchetypeRenderModel();
init();
//helper to get $eval the labelTemplate
$scope.getFieldsetTitle = function(fieldsetConfigModel, fieldsetIndex) {
var fieldset = $scope.archetypeRenderModel.fieldsets[fieldsetIndex];
var fieldset = $scope.model.value.fieldsets[fieldsetIndex];
var fieldsetConfig = $scope.getConfigFieldsetByAlias(fieldset.alias);
var template = fieldsetConfigModel.labelTemplate;
@@ -44,7 +41,7 @@
cursor: "move",
handle: ".handle",
update: function (ev, ui) {
},
stop: function (ev, ui) {
@@ -61,11 +58,11 @@
if (typeof $index != 'undefined')
{
$scope.archetypeRenderModel.fieldsets.splice($index + 1, 0, newFieldset);
$scope.model.value.fieldsets.splice($index + 1, 0, newFieldset);
}
else
{
$scope.archetypeRenderModel.fieldsets.push(newFieldset);
$scope.model.value.fieldsets.push(newFieldset);
}
}
@@ -74,15 +71,10 @@
}
}
//rather than splice the archetypeRenderModel, we're hiding this and cleaning onFormSubmitting
$scope.removeRow = function ($index) {
if ($scope.canRemove()) {
if (confirm('Are you sure you want to remove this?')) {
$scope.archetypeRenderModel.fieldsets[$index].remove = true;
/*
Touches the model. Not sure why this is needed but without it the Digest doesn't run on a remove row.
*/
$scope.archetypeRenderModel = JSON.parse(JSON.stringify($scope.archetypeRenderModel));
$scope.model.value.fieldsets.splice($index, 1);
}
}
}
@@ -118,12 +110,15 @@
}
//helper, ini the render model from the server (model.value)
function initArchetypeRenderModel() {
$scope.archetypeRenderModel = removeNulls($scope.model.value);
function init() {
$scope.model.value = removeNulls($scope.model.value);
addDefaultProperties($scope.model.value.fieldsets);
}
_.each($scope.archetypeRenderModel.fieldsets, function (fieldset)
function addDefaultProperties(fieldsets)
{
_.each(fieldsets, function (fieldset)
{
fieldset.remove = false;
fieldset.collapse = false;
fieldset.isValid = true;
});
@@ -144,6 +139,15 @@
return (typeof property !== 'undefined') ? property.value : '';
};
$scope.isCollapsed = function(fieldset)
{
if(typeof fieldset.collapse === "undefined")
{
fieldset.collapse = true;
}
return fieldset.collapse;
}
//helper for expanding/collapsing fieldsets
$scope.focusFieldset = function(fieldset){
fixDisableSelection();
@@ -159,13 +163,13 @@
iniState = fieldset.collapse;
}
_.each($scope.archetypeRenderModel.fieldsets, function(fieldset){
_.each($scope.model.value.fieldsets, function(fieldset){
fieldset.collapse = true;
});
if(!fieldset && $scope.archetypeRenderModel.fieldsets.length == 1 && $scope.archetypeRenderModel.fieldsets[0].remove == false)
if(!fieldset && $scope.model.value.fieldsets.length == 1)
{
$scope.archetypeRenderModel.fieldsets[0].collapse = false;
$scope.model.value.fieldsets[0].collapse = false;
return;
}
@@ -179,7 +183,7 @@
$scope.focusFieldset();
//developerMode helpers
$scope.archetypeRenderModel.toString = stringify;
$scope.model.value.toString = stringify;
//encapsulate stringify (should be built into browsers, not sure of IE support)
function stringify() {
@@ -187,12 +191,12 @@
}
//watch for changes
$scope.$watch('archetypeRenderModel', function (v) {
$scope.$watch('model.value', function (v) {
if ($scope.model.config.developerMode) {
console.log(v);
if (typeof v === 'string') {
$scope.archetypeRenderModel = JSON.parse(v);
$scope.archetypeRenderModel.toString = stringify;
$scope.model.value = JSON.parse(v);
$scope.model.value.toString = stringify;
}
}
});
@@ -200,64 +204,7 @@
//helper to count what is visible
function countVisible()
{
var count = 0;
_.each($scope.archetypeRenderModel.fieldsets, function(fieldset){
if (fieldset.remove == false) {
count++;
}
});
return count;
}
//helper to sync the model to the renderModel
function syncModelToRenderModel()
{
$scope.model.value = { fieldsets: [] };
_.each($scope.archetypeRenderModel.fieldsets, function(fieldset){
var cleanedFieldset = cleanFieldset(fieldset);
if(cleanedFieldset){
$scope.model.value.fieldsets.push(cleanedFieldset);
}
});
}
//helper to remove properties only used during editing that we don't want in the saved data
//also removes properties that are no longer in the config
function cleanFieldset(fieldset)
{
if (typeof fieldset != 'function' && !fieldset.remove){
var fieldsetConfig = $scope.getConfigFieldsetByAlias(fieldset.alias);
//clone and clean
var tempFieldset = JSON.parse(JSON.stringify(fieldset));
delete tempFieldset.remove;
delete tempFieldset.isValid;
delete tempFieldset.collapse;
_.each(tempFieldset.properties, function(property, index){
var propertyConfig = _.find(fieldsetConfig.properties, function(p){
return property.alias == p.alias;
});
//just prune the property
if(propertyConfig){
delete property.isValid;
}
else
{
//need to remove the whole property
tempFieldset.properties.splice(index, 1);
}
});
return tempFieldset;
}
return $scope.model.value.fieldsets.length;
}
// helper to get initial model if none was provided
@@ -270,7 +217,7 @@
//helper to add an empty fieldset to the render model
function getEmptyRenderFieldset (fieldsetModel) {
return {alias: fieldsetModel.alias, remove: false, isValid: true, properties: []};
return {alias: fieldsetModel.alias, collapse: false, isValid: true, properties: []};
}
//helper to ensure no nulls make it into the model
@@ -300,9 +247,9 @@
//helper to lookup validity when given a fieldsetIndex and property alias
$scope.getPropertyValidity = function(fieldsetIndex, alias)
{
if($scope.archetypeRenderModel.fieldsets[fieldsetIndex])
if($scope.model.value.fieldsets[fieldsetIndex])
{
var property = _.find($scope.archetypeRenderModel.fieldsets[fieldsetIndex].properties, function(property){
var property = _.find($scope.model.value.fieldsets[fieldsetIndex].properties, function(property){
return property.alias == alias;
});
}
@@ -310,23 +257,6 @@
return (typeof property == 'undefined') ? true : property.isValid;
}
//sync things up on save
$scope.$on("formSubmitting", function (ev, args) {
//test for form; may have to do this differently for nested archetypes
if(!form)
return;
if(form.$invalid)
{
notificationsService.warning("Cannot Save Document", "The document could not be saved because of missing required fields.")
}
else
{
syncModelToRenderModel();
}
});
//custom js
if ($scope.model.config.customJsPath) {
assetsService.loadJs($scope.model.config.customJsPath);
+5 -10
View File
@@ -1,5 +1,5 @@
<div class="archetypeEditor ng-class:model.config.customCssClass" ng-controller="Imulus.ArchetypeController">
<textarea class="archetypeDeveloperModel" ng-show="model.config.developerMode" ng-model="archetypeRenderModel"></textarea>
<textarea class="archetypeDeveloperModel" ng-show="model.config.developerMode" ng-model="model.value"></textarea>
<div class="archetypeFieldsetToolbar" ng-show="model.config.fieldsets.length > 1 && model.config.hideFieldsetToolbar != '1'">
<ul>
<li ng-repeat="fieldsetModel in model.config.fieldsets" ng-click="addRow(fieldsetModel.alias)">
@@ -8,29 +8,25 @@
</li>
</ul>
</div>
<ul ui-sortable="sortableOptions" ng-model="archetypeRenderModel.fieldsets" ng-show="!showAddButton()">
<li ng-repeat="fieldset in archetypeRenderModel.fieldsets" ng-hide="fieldset.remove">
<ul ui-sortable="sortableOptions" ng-model="model.value.fieldsets" ng-show="!showAddButton()">
<li ng-repeat="fieldset in model.value.fieldsets">
<fieldset ng-class="{archetypeFieldsetError: !fieldset.isValid}" ng-init="fieldsetConfigModel = getConfigFieldsetByAlias(fieldset.alias)">
<div class="archetypeFieldsetLabel" ng-class="{enableCollapsing: model.config.enableCollapsing}">
<div ng-click="focusFieldset(fieldset)" class="label-sub module-label">
<span class="caret" ng-hide="fieldset.collapse || !model.config.enableCollapsing"></span>
<span class="caret caret-right" ng-show="fieldset.collapse && model.config.enableCollapsing"></span>
<label>
<i class="fieldsetIcon icon ng-class:fieldsetConfigModel.icon"></i>
<span ng-bind="getFieldsetTitle(fieldsetConfigModel, $index)"></span>
</label>
</div>
<div class="archetypeEditorControls label-sub" ng-hide="model.config.hideFieldsetControls">
<i class="icon icon-add" ng-click="addRow(fieldset.alias, $index)" ng-show="canAdd()"></i>
<i class="icon icon-remove" ng-click="removeRow($index)" ng-show="canRemove()"></i>
<i class="icon icon-navigation handle" ng-show="canSort()"></i>
</div>
</div>
<div class="archetypeCollapser animate-hide" ng-hide="fieldset.collapse">
<div class="archetypeCollapser animate-hide" ng-hide="isCollapsed(fieldset)">
<form class="form-inline">
<div ng-class="{archetypePropertyError: getPropertyValidity($parent.$index, property.alias) === false}" class="archetypeProperty control-group" ng-repeat="property in fieldsetConfigModel.properties">
<label ng-hide="archetypeConfig.hidePropertyLabels == '1'" class="control-label" for="archetype-property-{{model.alias}}-{{$parent.$index}}-{{$index}}">
@@ -41,7 +37,7 @@
</label>
<div class="controls">
<archetype-property class="archetypeEditor ng-class:property.alias" property="property" fieldset-index="$parent.$index" fieldset="fieldset" archetype-config="model.config" property-config-index="$index" archetype-render-model="archetypeRenderModel" umbraco-property-alias="model.alias"></archetype-property>
<archetype-property class="archetypeEditor ng-class:property.alias" property="property" fieldset-index="$parent.$index" fieldset="fieldset" archetype-config="model.config" property-config-index="$index" archetype-render-model="model.value" umbraco-property-alias="model.alias"></archetype-property>
</div>
</div>
</form>
@@ -49,7 +45,6 @@
</fieldset>
</li>
</ul>
<div ng-show="showAddButton()">
<a class="archetypeAddButton" href="#" ng-click="addRow(model.config.fieldsets[0].alias, 0)" prevent-default="">
<i class="icon icon-add"></i>