[ Trouble updating complex model via Angular UI modal ]
I have a model with nested arrays corresponding to sections of a floor plan. Within each of the floor plan's sections is an array of booth objects. Let's say I have a view of this data that displays all of the booths on a grid, allowing the user to click on a booth icon (thus generating an Angular UI modal) and edit that booth's data. The problem is that, when it's time for the user to save the updated booth info, I'm unsure of how to associate the selected booth model with the appropriate section and, within that section, the correct booth model. Could someone help point me in the right direction here?
Here's my code.
boothManager.js
var boothManager = angular.module("boothManager", ["ui.bootstrap"]);
boothManager.controller("BoothManagerCtrl", function ($scope, $modal, $log) {
$scope.open = function (booth) {
var modalInstance = $modal.open({
templateUrl: '../../templates/edit_booth.html',
controller: "EditBoothCtrl",
backdrop: true,
size: "sm",
resolve: {
boothData: function () {
return booth;
}
}
});
modalInstance.result.then(function (boothData) {
console.log(boothData);
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
$scope.viewModel = {
"sections": [
{
"id": "String",
"name": "String",
"booths": [
{
"number": 1,
"fee": 30000,
"width": "10",
"length": "10",
"xPosition": 100,
"yPosition": 100,
"type": "String",
"label": "String",
"radius": 15
},
{
"number": "2",
"fee": 30000,
"width": "20",
"length": "20",
"xPosition": 132,
"yPosition": 100,
"type": "String",
"label": "String",
"radius": 15
},
{
"number": "3",
"fee": 30000,
"width": "10",
"length": "10",
"xPosition": 164,
"yPosition": 100,
"type": "String",
"label": "String",
"radius": 15
},
{
"number": "4",
"fee": 30000,
"width": "10",
"length": "10",
"xPosition": 196,
"yPosition": 100,
"type": "String",
"label": "String",
"radius": 15
},
{
"number": "5",
"fee": 30000,
"width": "10",
"length": "10",
"xPosition": 228,
"yPosition": 100,
"type": "String",
"label": "String",
"radius": 15
}
]
},
{
"id": "String",
"name": "String",
"booths": [
{
"number": "1",
"fee": 20000,
"width": "10",
"length": "10",
"xPosition": 100,
"yPosition": 132,
"textXPosition": 1,
"textYPosition": 1,
"type": "String",
"label": "String",
"radius": 15
},
{
"number": "2",
"fee": 20000,
"width": "20",
"length": "20",
"xPosition": 132,
"yPosition": 132,
"type": "String",
"label": "String",
"radius": 15
},
{
"number": "3",
"fee": 20000,
"width": "10",
"length": "10",
"xPosition": 164,
"yPosition": 132,
"type": "String",
"label": "String",
"radius": 15
},
{
"number": "4",
"fee": 20000,
"width": "10",
"length": "10",
"xPosition": 196,
"yPosition": 132,
"type": "String",
"label": "String",
"radius": 15
},
{
"number": "5",
"fee": 20000,
"width": "10",
"length": "10",
"xPosition": 228,
"yPosition": 132,
"type": "String",
"label": "String",
"radius": 15
}
]
},
{
"id": "String",
"name": "String",
"booths": [
{
"number": "1",
"fee": 10000,
"width": "10",
"length": "10",
"xPosition": 100,
"yPosition": 164,
"type": "String",
"label": "String",
"radius": 15
},
{
"number": "2",
"fee": 10000,
"width": "20",
"length": "20",
"xPosition": 132,
"yPosition": 164,
"type": "String",
"label": "String",
"radius": 15
},
{
"number": "3",
"fee": 10000,
"width": "10",
"length": "10",
"xPosition": 164,
"yPosition": 164,
"type": "String",
"label": "String",
"radius": 15
},
{
"number": "4",
"fee": 10000,
"width": "10",
"length": "10",
"xPosition": 196,
"yPosition": 164,
"type": "String",
"label": "String",
"radius": 15
},
{
"number": "5",
"fee": 10000,
"width": "10",
"length": "10",
"xPosition": 228,
"yPosition": 164,
"type": "String",
"label": "String",
"radius": 15
}
]
}
]
};
});
var EditBoothCtrl = function ($scope, $modalInstance, boothData) {
$scope.booth = angular.copy(boothData)
$scope.original = angular.extend($scope.booth);
$scope.ok = function () {
boothData = $scope.booth;
$modalInstance.close(boothData);
};
$scope.cancel = function () {
$scope.booth = angular.copy($scope.original);
$modalInstance.close();
};
};
Here's a dumbed-down copy of my section view's markup:
boothManager.html
<div ng-app="boothManager" ng-controller="BoothManagerCtrl" ngCloak>
<div ng-repeat="section in viewModel.sections">
<div ng-repeat="booth in section.booths" ng-click="open(booth)">
</div>
</div>
</div>
Here's my modal's markup:
modal.html
<div>
<!--<script type="text/ng-template" id="edit_booth.html">-->
<div class="modal-header">
<h3 class="modal-title">Booth info</h3>
</div>
<div class="modal-body">
<form name="editBoothForm">
<input placeholder="label" ng-model="booth.label" />
<input placeholder="Width" ng-model="booth.width" />
<input placeholder="Length" ng-model="booth.length" />
</form>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">Save</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
<!-- </script>-->
</div>
Answer 1
If it were me, I will pass in a bit more information into the model that is passed into modal controller. Section object can be passed in directly, while individual booth object is identified by the its index inside the array:
// here, we pass in index number, and the owning section
$scope.open = function (booth, index, section) {
var modalInstance = $modal.open({
templateUrl: '../../templates/edit_booth.html',
controller: "EditBoothCtrl",
backdrop: true,
size: "sm",
resolve: {
boothData: function () {
// pass along these info into the object you inject
// into your modal controller
data = {
index: index,
section: section
};
return angular.copy(booth, data);
}
}
});
modalInstance.result.then(function (boothData) {
// here bootData.index and bootData.section exists
bootData.section.booths[bootData.index] = bootData;
// cleaning up since we no longer need them
delete bootData.index;
delete bootData.section;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
Then, in your ng-repeat
:
<div ng-repeat="section in viewModel.sections">
<div ng-repeat="booth in section.booths" ng-click="open(booth, $index, section)">
</div>
</div>