Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the idiomatic way of communicating between Onsen popover and its parent?

Tags:

onsen-ui

This is what I've got so far. First the script:

ons.bootstrap();
.controller('AppController', function($scope) {
  $scope.greeting = "Hello!";
  ons.createPopover('popover.html').then(function(popover) {
    $scope.popover = popover;
    popover.on('preshow', function() {
      popover._scope.greeting = $scope.greeting;
    });
    popover.on('posthide', function() {
      $scope.greeting = popover._scope.greeting;
      $scope.$apply();
    });
  });
});

And the page:

<ons-page ng-controller="AppController">
  <ons-toolbar>
    <div class="center">Popover</div>
  </ons-toolbar>

  <div style="margin-top: 100px; text-align: center">
    <ons-button modifier="light" ng-click="popover.show($event)">Show popover</ons-button>
  </div>
  <div style="margin-top: 100px; text-align: center">{{greeting}}</div>

</ons-page>

<ons-template id="popover.html">
  <ons-popover direction="up down" cancelable>
    <div style="text-align: center; opacity: 0.8;">
      <input style="margin: 20px" type="text" ng-model="greeting" />
    </div>
  </ons-popover>
</ons-template>

This seems to work for me, but I'm not sure about the popover._scope part. Is it supposed to be accessed like that? I can't seem to find any other way.

So what is the idiomatic way to do this? And what are some good examples?

Thank you.

like image 217
Wang Dingwei Avatar asked Sep 24 '15 08:09

Wang Dingwei


1 Answers

You can use the parentScope parameter to make the popover scope a descendant of the AppController scope:

module.controller('AppController', function($scope) {
  ons.createPopover('popover.html', {parentScope: $scope});
});

Now you have some options on how to communicate between the scopes. Since the popover scope is a descendant of the AppController scope you can for instance use $scope.$emit() to emit events when the value changes:

module.controller('AppController', function($scope) {
  $scope.greeting = 'Hello!';

  ons.createPopover('popover.html', {parentScope: $scope}).then(function(popover) {
    $scope.popover = popover;
  });

  $scope.$on('update', function(event, value) {
    $scope.greeting = value;
  });
})

.controller('PopoverController', function($scope) {
  $scope.$watch('greeting', function(value) {
    $scope.$emit('update', value);
  });
});

I made a simple example: http://codepen.io/argelius/pen/avmqOP

You can also use ngModel to access the the value but keep in mind that it's actually the grandparent so in that case you need to do ng-model="$parent.$parent.greeting" which is not very nice.

I would recommend the event approach.

like image 104
Andreas Argelius Avatar answered Sep 17 '22 11:09

Andreas Argelius