javascript - WebSocket Service update Scope in Angular (Using ngWebSocket)? - Stack Overflow

I'm trying to get data ing from a websocket to automatically update value inside a controller'

I'm trying to get data ing from a websocket to automatically update value inside a controller's scope.

My Service:

mimosaApp.service("Device", function ($websocket) {
    var self = this;
    var ws = $websocket.$new({
        url: "ws://" + window.location.host + ":81",
        //mock: true,
        reconnect: true
    });
    this.data = {};

    ws.$on("$open", function() {
        ws.$emit("get", "device");
    });
    ws.$on("$message", function (message) {
        console.log("WS Received", message);
        for(var key in message) {
            self.data[key] = message[key];
        }
        console.log(self.data); // At this point, self.data contains the proper data.
    });
    this.send = function (obj) {
        ws.$emit("set", obj);
    };
});

And my simple controller:

angular.module("MimosaApp").controller("PageController", ["Device", "$scope", "$http", function(Device, $scope, $http) {
    $scope.device = Device;
}]);

When a socket connection is made, the browser sends a message asking for data (the $open event). When it gets a response, it updates the Device.data object with the JSON object.

But I'm not seeing this reflect inside my controller scope/view. If inside the Controller, I set something like Device.data.name ='blah'; I can see the name property in the controller scope/view.

I'm a little new to Angular so sorry if my question doesn't quite make sense. :)

My view is trying to use it like:

<div class="container-fluid">
    location
    <ul>
        <li ng-repeat="(key, value) in device.data">
            {{key}}: {{ value }}
        </li>
    </ul>
    <p>{{device.data.face}}</p>
</div>

I'm trying to get data ing from a websocket to automatically update value inside a controller's scope.

My Service:

mimosaApp.service("Device", function ($websocket) {
    var self = this;
    var ws = $websocket.$new({
        url: "ws://" + window.location.host + ":81",
        //mock: true,
        reconnect: true
    });
    this.data = {};

    ws.$on("$open", function() {
        ws.$emit("get", "device");
    });
    ws.$on("$message", function (message) {
        console.log("WS Received", message);
        for(var key in message) {
            self.data[key] = message[key];
        }
        console.log(self.data); // At this point, self.data contains the proper data.
    });
    this.send = function (obj) {
        ws.$emit("set", obj);
    };
});

And my simple controller:

angular.module("MimosaApp").controller("PageController", ["Device", "$scope", "$http", function(Device, $scope, $http) {
    $scope.device = Device;
}]);

When a socket connection is made, the browser sends a message asking for data (the $open event). When it gets a response, it updates the Device.data object with the JSON object.

But I'm not seeing this reflect inside my controller scope/view. If inside the Controller, I set something like Device.data.name ='blah'; I can see the name property in the controller scope/view.

I'm a little new to Angular so sorry if my question doesn't quite make sense. :)

My view is trying to use it like:

<div class="container-fluid">
    location
    <ul>
        <li ng-repeat="(key, value) in device.data">
            {{key}}: {{ value }}
        </li>
    </ul>
    <p>{{device.data.face}}</p>
</div>
Share Improve this question edited May 19, 2015 at 23:34 Charlie asked May 19, 2015 at 23:28 CharlieCharlie 1,7665 gold badges24 silver badges44 bronze badges 0
Add a ment  | 

2 Answers 2

Reset to default 3

Looking at the source it does not seem to invoke digest cycle using scope.$apply within the $on handler. Which means that angular does not know about any update to its view bindings, so no change gets reflected in the view. So you would need to do it manually in your service, you could either inject a $rootScope or just a $timeout to trigger a digest cycle.

Example:-

inject $timeout

 ws.$on("$message", function (message) {
        console.log("WS Received", message);
        for(var key in message) {
            self.data[key] = message[key];
        }
        console.log(self.data); // At this point, self.data contains the proper data.
       $timeout(angular.noop); //<-- just invoke a dummy digest
    });

inject $rootScope

 ws.$on("$message", function (message) {
        console.log("WS Received", message);
        for(var key in message) {
            self.data[key] = message[key];
        }
        console.log(self.data); // At this point, self.data contains the proper data.
      $rootScope.$apply(); //invoke digest
    });

Or even create a dummy promise in your service using $q.

mimosaApp.service("Device", function ($websocket, $q) {
    var self = this;
    var _dummyPromise = $q.when(); //<-- here
    var ws = $websocket.$new({
        url: "ws://" + window.location.host + ":81",
        //mock: true,
        reconnect: true
    });
    //...


    ws.$on("$message", function (message) {
        console.log("WS Received", message);
        for(var key in message) {
            self.data[key] = message[key];
        }
       _dummyPromise.then(angular.noop); //<-- here
    });
    this.send = function (obj) {
        ws.$emit("set", obj);
    };
});

The most likely cause is that the $on callback isn't triggering a $digest cycle to inform the rest of the app of any change.

You can do that manually by injecting $rootScope

mimosaApp.service("Device", function ($rootScope, $websocket)

and then triggering a $digest after updating your data

ws.$on("$message", function (message) {
    console.log("WS Received", message);
    for(var key in message) {
        self.data[key] = message[key];
    }
    if(!$rootScope.$$phase) { // prevents triggering a $digest if there's already one in progress
        $rootScope.$digest()
    }
    console.log(self.data); // At this point, self.data contains the proper data.
});

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745090505a4610666.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信