2

Someone please give me an idea how to solve this. In my main file I use startEdit($index) function that grabs the input value, that has to be changed, and redirect me to /edit partial. Here I type a new text in the input box and use save() to save the new value and then redirect me back to main view, where I can see the new text.

The problem is that I don't get in the save() function the new value for $rootScope.siteBox; . I get the same old value, even in the $watch function I can see that the variable is changing.

I tried a lot of solutions but with no result. Someone please give a hand and tell me what is wrong.

JS FILE

    angular.module('maintenance', ['ngRoute'])
    .controller('siteEditCtrl', SiteEditCtrl)
    .controller('mainCtrl', MainCtrl)
    .controller('addCtrl', AddCtrl)
    .controller('editCtrl', EditCtrl)
    .controller('deteleCtrl', DeteleCtrl)
    .config(function($routeProvider) {
        $routeProvider.
        when('/', {
            templateUrl: 'views/lists.html', 
            controller: 'mainCtrl'
        })
        .when('/add', {
            templateUrl: 'views/add.html',
            controller: 'addCtrl'
        })
        .when('/edit', {
            templateUrl: 'views/edit.html',
            controller: 'editCtrl'
        })
        .when('/detele', {
            templateUrl: 'views/detele.html',
            controller: 'deteleCtrl'
        })
        .otherwise({
            redirectTo: '/'
        });
    });

function SiteEditCtrl($scope, $location, $rootScope) {
    $rootScope.sites = sites;
    $rootScope.selected = -1;

    $scope.startAdd = function() {
       $location.path( "/add" );
    };

    $scope.startEdit = function(index) {
        $rootScope.selected = index;
        $rootScope.siteBox = $rootScope.sites[index];
        //console.log($rootScope.siteBox);
        $location.path( "/edit" );
    };
}

 function EditCtrl($scope, $location, $rootScope) {
    $scope.$watch('siteBox', function(newValue, oldValue) {
        //console.log(oldValue);
        //console.log(newValue);
    });
    $scope.save = function() {
        console.log($rootScope.siteBox);
        $rootScope.sites[$rootScope.selected] = $rootScope.siteBox;
        $location.path( "#/" );
    };
}

Main view in config(/)

         <div class="row">
            <div class="col-sm-12">
                    <a class="btn btn-primary btn-lg" ng-click="startAdd()">
                        Add new dive 
                    </a>
            </div>
        </div>
       <h2>List of Dive Sites</h2>
        <div class="row" ng-repeat="site in sites"
               ng-class="{oddRow: $index % 2 == 0}">
            <div class="col-sm-8">
              <h4>{{$index + 1}}: {{site}}</h4>
            </div>
            <div class="col-sm-4" style="margin-top: 5px;">
                <div class="pull-right">
                    <button class="btn btn-warning btn-sm" ng-click="startEdit($index)">
                      Edit
                    </button>
                    <button class="btn btn-danger btn-sm" ng-click="startRemove($index)">
                      Delete
                    </button>
                </div>
            </div>
        </div>

Edit view in config(/edit)

        <h3>Edit the dive site name</h3>
        <div class="row">
            <div class="col-sm-6">
                <input type="text" class="form-control input-lg" placeholder="site name" ng-model="siteBox">
            </div>
        </div>
        <div class="row" style="margin-top: 12px;">
            <div class="col-sm-6">
                <button class="btn btn-succes btn" ng-disabled="siteBox==''" ng-click="save()">
                    Save
                </button>
                <button class="btn btn-warning btn" ng-click="cancel()">
                    Cancel
                </button>
            </div>
        </div>
  • Why is `$scope.startEdit()` defined _inside_ another function? I'm not sure that you are ever setting the `siteBox` property on your root scope. – Tim Biegeleisen Nov 29 '16 at 01:26
  • @TimBiegeleisen The code as shown is fine, and typical Angular 1 code, albeit using old practices like putting methods on `$scope` instead of controller instances, but it will work. The problem is to do with the binding expression used for `ng-model`. – GregL Nov 29 '16 at 01:29
  • If I use one controller and no partials with config everything work fine, but with partials no. I'm learning angularjs, I'm not a pro. –  Nov 29 '16 at 01:32
  • It's great that you are learning, John. Just make sure to learn current best practices, like using components instead of raw controllers, so you're not learning outdated practices from the beginning, and you don't have to unlearn them later. The reason it doesn't work with more than one controller and partials is because each controller and partial adds a new scope to the hierarchy, which breaks your `ng-model` expression. – GregL Nov 29 '16 at 01:37
  • But when I use $rootScope this doesn't carry the same value for all controllers? –  Nov 29 '16 at 10:08

2 Answers2

0

To share variables among views consider using a Factory/Service. You can store the sites in the factory and update/retrieve whenever necessary.

Sajeetharan
  • 216,225
  • 63
  • 350
  • 396
  • I don't know how to use a service here. I tried that too, believe me, but I guess I didn't set it up right –  Nov 29 '16 at 01:35
  • @JohnSmith if this is going to be a large scale app, consider changing it – Sajeetharan Nov 29 '16 at 01:38
  • no my friend, it's just for learning, and this with a few more functions is the whole test project –  Nov 29 '16 at 01:41
  • @JohnSmith ok, then consider assigning the $rootscope variable to a $scope variable , you will be able to see the changes and updates – Sajeetharan Nov 29 '16 at 01:43
  • if u can give me some indications about how to put those two functions in a service, startEdit() and save(), I will thank you, because the problem my friend is between those two functions that are in diff controllers. –  Nov 29 '16 at 01:54
  • @JohnSmith https://jsfiddle.net/sajeetharan/q0rwjsdm/ check this sample – Sajeetharan Nov 29 '16 at 02:00
0

This is a classic case of violating the "dot rule" for ng-model.

Effectively, by having ng-model="siteBox" in your markup, when the input value gets changed, a siteBox property is set on the scope for editCtrl, not on $rootScope as you expect.

Instead, use $rootScope.data.siteBox in controller code and data.siteBox in view code instead of $rootScope.siteBox/siteBox so that you set the property on the correct object. Make sure to initialise $rootScope.data to an empty object early on.

Community
  • 1
  • 1
GregL
  • 37,147
  • 8
  • 62
  • 67
  • my friend I tried what you said but nothing changed. I replaced the the values but no result –  Nov 29 '16 at 01:51