0

I'm trying to simply change the button text with a toggle but I'm failing to do so I don't know why.The button only shows 'ver fotos' and doesnt change to my 2nd option. Maybe i can't put two ng-click like that? This is my code:

angular.module('app.controllers', [])
.controller('perfilCtrl', ['$scope', '$stateParams', "detailService",// The following is the constructor function for this page's controller. See https://docs.angularjs.org/guide/controller
// You can include any angular dependencies as parameters for this function
// TIP: Access Route Parameters for your page via $stateParams.parameterName
function ($scope, $stateParams, detailService) {
$scope.detalhes=detailService.data;
$scope.goEsconder = false;
$scope.toggle = true;
$scope.$watch('toggle', function(){
$scope.toggleText = $scope.toggle ? 'Ver fotos' : 'Ver características';
   })

}])
<ion-view id="page4">
    <ion-content padding="true" class="backg">
        <div class="row">
            <div class="col">
                <h3 class="name">{{detalhes[0]}}</h3>
            </div>
        </div>
        <div class="row">
            <div class="col">
                <p class="descricao">{{detalhes[2]}}</p>
            </div>
        </div>
        <div class="row">
            <div class="col text-center" ui-sref="contacto"><button class="button b2">
                Contactar
                </button>
            </div>
            <div class="col text-center"><button class="button b3" ng-click="goEsconder = !goEsconder; toggle = !toggle">
                {{toggleText}}
                </button>
            </div>
        </div>
    </ion-content>
</ion-view>
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189

3 Answers3

0

I believe it works fine: http://jsfiddle.net/Lvc0u55v/10594/

var myApp = angular.module('myApp',[]);

function MyCtrl($scope) {
    $scope.toggleText = 'click me'
    $scope.toggle = true
    $scope.$watch('toggle', function(){
        $scope.toggleText = $scope.toggle ? 'Ver fotos' : 'Ver características';
    })
}

Html:

<div ng-controller="MyCtrl">
    <div class="col text-center">
        <button class="button b3" ng-click="toggle = !toggle">{{toggleText}}</button>
    </div>
</div>
Martin Gottweis
  • 2,721
  • 13
  • 27
  • its not working here, im testing it on ionic lab. maybe its cause of the child scope thing? –  Oct 07 '16 at 14:32
  • 1
    @MárioSouto yes very high probability it is a child scope nesting issue as there are lots of directives that create child scope but you haven't shown enough context for anyone to know for sure – charlietfl Oct 07 '16 at 14:33
  • 1
    Maybe add more code surrounding the `
    `.
    – Martin Gottweis Oct 07 '16 at 14:37
  • @MartinGottweis just edited my code, does that help? –  Oct 07 '16 at 14:44
  • 1
    Ehm, where is the `perfilCtrl` controller? – Martin Gottweis Oct 07 '16 at 14:47
  • @MartinGottweis .state('perfil', { url: '/page4', templateUrl: 'templates/perfil.html', controller: 'perfilCtrl' }) –  Oct 07 '16 at 14:47
  • 1
    `ion-content` creates it's own scope. Maybe you can create a new `toggler` directive and use it on the button. @charlietfl also suggested the object thing that will make the toggle accessible even if it's defined in parent scope. – Martin Gottweis Oct 07 '16 at 14:51
0

Use an object so that child scopes will use inheritance. There is no inheritance on primitives in javascript.

So what happens is you are only changing the primitive in the child scope and that change is hidden from the parent so the watch won't fire

  $scope.myModel = { toggle: true };
  $scope.$watch('myModel.toggle', function(nVal, oVal) {
    $scope.toggleText = $scope.myModel.toggle ? 'Ver fotos' : 'Ver características';
  });

HTML

<button class="button b3" ng-click="myModel.toggle = !myModel.toggle">
  {{toggleText}}
</button>

DEMO

charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • 1
    Alternatively if you had used a function to do the boolean toggle in controller it would have also worked. Angular internal scope watches would have updated the child scope – charlietfl Oct 07 '16 at 14:58
-1

Change your watcher to use the true parameter, this way:

$scope.$watch('toggle', function(toggle){
   $scope.toggleText = toggle ? 'Ver fotos' : 'Ver características';
}, true)

this will make your code work because watchers doesn't work natively on boolean values (because boolean values are passed by value on javascript: for your watcher toggle is always true )

Specifying the true parameter, however, will change your watcher to a deep watcher, being so able to catch value changes and not only references changes.

illeb
  • 2,942
  • 1
  • 21
  • 35
  • It still doesnt toggle between the two :\ –  Oct 07 '16 at 14:14
  • 1
    include the variable as parameter too, like shown in my answer. – illeb Oct 07 '16 at 14:16
  • 2
    This is nonsense. Watch works fine on a primitive. OP's code works when not nested in a child scope – charlietfl Oct 07 '16 at 14:22
  • 1
    False. check this answer http://stackoverflow.com/a/17795221/1306679 and the documentation: https://docs.angularjs.org/api/ng/type/$rootScope.Scope "when objectEquality == true, inequality of the watchExpression is determined according to the angular.equals function" – illeb Oct 07 '16 at 14:27
  • 1
    that is about objects. You are misinterpreting what you are reading. Also i posted a link in comments showing that it works – charlietfl Oct 07 '16 at 14:28