Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • mcgrph 35 posts 162 karma points
    Feb 05, 2018 @ 18:20
    mcgrph
    0

    dialogService updates main view model instantly

    I discovered a (in my opinion) weird behavior. If I open a dialogService from my plugin I pass a specific part of my $scope.model.value (an array with nested objects in this case) like this:

    angular.module("umbraco").controller("myController", function ($scope, dialogService) {
    
        // Main controller
        $scope.doSomething = function (index) {
            dialogService.open({
                template: '/path/to/template.html',
                show: true,
                modelData: $scope.model.value.array[index],
                callback: function (data) {
                    $scope.model.value.array[index] = data;
                }
            });
        };
    }
    
    angular.module("umbraco").controller("myDialogController", function ($scope) {
    
        // Dialog controller
        if ($scope.$parent.dialogOptions.modelData === null || $scope.$parent.dialogOptions.modelData === undefined) {
            $scope.modelData = [];
        } else {
            $scope.modelData = $scope.$parent.dialogOptions.modelData;
        }
    
         // some method
        $scope.myFunction = function () {
    
            // create new object
            var item = { prop1: "", prop2: "" };
    
            // push to array
            $scope.modelData.push(item)
    
        }
    }
    
    • The behavior I would expect is the following:

      I edit some/none/all of the data in my dialog, click submit and then the changed data are given back to my model in the plugin (in this case a new object was added to the array).

    • What actually happens:

      I edit some/none/all of the data in my dialog and the plugin model is updated instantly (the object is pushed to my plugin view model as soon as I push it to array in the plugin).

    This means for example, if I accidentally delete something in my dialog it can't be undone by just pressing "cancel".

    Should I use model.control instead and just "sync" it onSubmit? But if so, how could that be achieved? Or am I missing out some important architectural feature from umbraco/angularjs at this point?

  • Kevin Jump 2310 posts 14695 karma points MVP 7x c-trib
    Feb 05, 2018 @ 19:17
    Kevin Jump
    0

    Hi

    i think the issue is that you are accessing the parent model, which is linked directly to you $scope.model.

    You can pass data to your dialog by settings the dialogData variable (not really documented as far as i can tell, but this appears to be how the core does it.)

    dialogService.open({
                template: '/path/to/template.html',
                show: true,
                dialogData: $scope.model.value.array[index],
                callback: function (data) {
                      ...
    

    you should then be able to access a detached version of this via $scope.dialogData

    you can then manipulate this value without changing the one on your parent page - returning the data into the callback and setting it on the item there.

  • mcgrph 35 posts 162 karma points
    Feb 06, 2018 @ 08:50
    mcgrph
    0

    Hi Kevin,

    many thanks for your fast reply. I gave it a try and implemented it like you were proposing:

    // main
    $scope.doSomething = function (index) {
        dialogService.open({
            template: 'path/to/template.html',
            show: true,
            dialogData: $scope.model.value.array[index],
            callback: function (data) {
                $scope.model.value.array[index] = data;
            }
        });
    }
    
    // dialog
    $scope.modelData = $scope.dialogData;
    

    But unfortunately the binding is still existing and updating my main view from inside the dialog if I change something.

  • Kevin Jump 2310 posts 14695 karma points MVP 7x c-trib
    Feb 06, 2018 @ 11:10
    Kevin Jump
    0

    did you also change this code ?

      // Dialog controller
        if ($scope.$parent.dialogOptions.modelData === null || $scope.$parent.dialogOptions.modelData === undefined) {
            $scope.modelData = [];
        } else {
            $scope.modelData = $scope.$parent.dialogOptions.modelData;
        }
    

    You should now be able to access $scope.dialogData as your model, binding back to the parent with $scope.$parent will update the main view so should be avoided.

  • mcgrph 35 posts 162 karma points
    Feb 06, 2018 @ 13:03
    mcgrph
    0

    Yes, I also changed the dialog controller. Please take a look at the last line of code on my previous reply. I just simplified the if/else construct.

  • mcgrph 35 posts 162 karma points
    Feb 14, 2018 @ 18:04
    mcgrph
    101

    So after I found no real solution for this problem, I managed to "fix" it with copying the datamodel to the scope in the dialog:

    // dialog
    $scope.modelData = angular.copy($scope.dialogData);
    

    And after doing all the fantastic angular stuff with it, I simply passed it back with save(modelData). This ensures, that the model in my main view is only updated after the user closes the dialog.

Please Sign in or register to post replies

Write your reply to:

Draft