Search code examples
angularjsdialogangular-materialcustomdialogmddialog

mddialog textarea model is not updated when changes in the main controller


This is a question about Angular Materials, mdDialogs and scope variables:

  • I am subscribed to a specific topic using Stomp.
  • Stomp receives Strings from the server that they are concatenated in a scope variable.
  • User clicks on a button to show a mdDialog.
  • mdDialog should show the incoming string changes in a textarea.

But...it is not working properly. I have to close and re-open the dialog to see the changes. I tried to add the textarea in the main view (index.html) and the textarea works properly.

Why doesn't it change the textarea when we are inside mdDialog in Angular Materials? Any idea to solve it?

This is the plunker you can see the main view (index.html) updates the random value properly, but if you open the dialog the value will not update properly...

https://plnkr.co/edit/teC69Sg7UqNbouHxpT22

var angularInstance = angular.module('ExampleApp', ['ngMaterial', 'ngMessages']) ;

angularInstance.controller('ExampleCtrl', function ExampleCtrl($scope, $mdDialog, $mdMedia, $interval)
{
    $scope.randomString = "" ;

    $scope.initialization = function()
    {
      $interval($scope.addRandomChar, 1000) ; 
    }

    $scope.addRandomChar = function()
    {
      $scope.randomString = $scope.randomString + "a" ;
    }

  $scope.openMyDialog = function(ev)
    {
        var useFullScreen = ($mdMedia('sm') || $mdMedia('xs'))  && $scope.customFullscreen ;
        $mdDialog.show({
            controller: myDialogController,
            templateUrl: 'myDialog.tmpl.html',
            parent: angular.element(document.body),
            targetEvent: ev,
            clickOutsideToClose:true,
            fullscreen: useFullScreen,
            resolve: 
            {
                randomString: function ()
                {
                    return $scope.randomString ;
                }
            }
        }) ;
    }
});

function myDialogController($scope, $mdDialog, randomString) 
{
    $scope.randomString = randomString ;

    $scope.close = function ()
    {
        $mdDialog.cancel() ;
    };
}

Many thanks.


Solution

  • Here you have a working plunker

    Summarising, I've slightly changed the way you pass the params from the ExampleCtrl to myDialogController, using locals.

    $mdDialog.show({
        controller: myDialogController,
        templateUrl: 'myDialog.tmpl.html',
        targetEvent: ev,
        locals: {parent: $scope},
        clickOutsideToClose:true,
        ...
    

    Then, in your dialog controller, you have access all parent scope:

    function myDialogController($scope, $mdDialog, parent) {
        $scope.parent = parent;
    
        ...
    }
    

    So finally, in the view you just need to bind parent.randomString to the textarea ng-model, and it will work as you expect:

    <textarea ... ng-model="parent.randomString"/>
    

    Cheers. Hope it helps.