質問

I try to get a json file via $http by calling a DataService periodically.

Then I want to use the $watch functionality to react to any data change. However the watch function never gets triggered more than once. Why?

var app = angular.module('myApp', ['ngRoute']).
    config(['$routeProvider', function ($routeProvider) {
        //...
    }])

    .

    run(function ($rootScope, $timeout, $location, DataService) {

        $rootScope.jsonData = {}

        var delaytime = 10 * 1000;

        $rootScope.jsonData = DataService.getData();

        $timeout(function repeat() {
                console.log("in repeat")
                $rootScope.jsonData = DataService.getData();
                $timeout(function () {
                        console.log("in inner repeat")
                        repeat();
                    }, delaytime
                );
            }, delaytime
        );



        console.log("xxx")
        console.log($rootScope.jsonData)
        $rootScope.$watch('jsonData', reactToDataChange($rootScope, $location));
    })


;


function reactToDataChange($rootScope, $location) {
    console.log("yyy")
    console.log($rootScope.jsonData)
    // ...
}

DataService:

app.service('DataService', function ($http) {

var data = null;

function setData(newdata) {
    data = newdata;
}

return {

    getData: function () {

        console.log("getting data");

        var rand = "?rand=" + Math.random() * 10000;
        $http.get('data/bla.json' + rand, {cache: false})

            .success(function (newdata) {
                console.log(newdata);
                setData(newdata);
            })
            .

            error(function (data, status, headers, config) {
                console.log("error");
                console.log(status)
            });


        return data;
    }
};
});

Console shows:

getting data 
xxx
null
yyy
null
new data:[object Object]
Object {bla: Object}
in repeat
getting data
new data:[object Object]
Object {bla: Object}
in inner repeat
in repeat
getting data
new data:[object Object]
Object {bla: Object}
in inner repeat
in repeat
...

Why is yyy not shown again?

役に立ちましたか?

解決

Short answer to your "Why?" is that $watch takes a function as a second parameter while you're passing reactToDataChange($rootScope,$location) which is a function call and returns undefined. It's easy to fix it by modifying reactToDataChange:

function reactToDataChange($rootScope, $location) {
    return function(){
        console.log("yyy")
        console.log($rootScope.jsonData)
        // ...
    }
}

By the way your repeat is overcomplicated. Why not try this:

var rep = function(){
    $timeout(function(){
        $rootScope.jsonData = DataService.getData();
        rep();
    },delaytime);
}
rep();

他のヒント

Try this:

$rootScope.$watch('jsonData', reactToDataChange($rootScope, $location), true);

Try to change

function reactToDataChange($rootScope, $location) {
    console.log("yyy")
    console.log($rootScope.jsonData)
}

to

function reactToDataChange($rootScope, $location) {
    return function(){
        console.log("yyy")
        console.log($rootScope.jsonData)
    }
}

You should apply true as third argument for $watch to start "deep watching" of jsonData object:

$rootScope.$watch('jsonData', reactToDataChange($rootScope, $location), true);

And you can access new value of jsonData without passing rootScope to callback, just use first argument:

$rootScope.$watch('jsonData', reactToDataChange, true);
....
function reactToDataChange(value) {
    console.log(value);
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top