Модель Angularjs изменяется после нажатия данных websocket с сервера

Я пытаюсь изменить свою угловую модель после нажатия websocket с сервера. Как можно изменить такие значения, как $scope.contacts каждый раз, когда сервер обрабатывает новые данные..?

Я не уверен, что это возможно с помощью $apply. Я знаю, что могу получить доступ к элементу DOM, получить область, а затем изменить значения, но должно быть лучшее решение!

меня действительно интересует решение для обновления угловой модели извне без создания углового модули, так как я использую относительные источники данных, которые испускают события изменений. Нет ли простого способа сделать это, как в Backbone.Яш, где вы можете сказать:

var book = new Backbone.Model({ title: 'value' });
book.set("title", "A Scandal in Bohemia");

то, что я хочу в angularjs, это что-то вроде:

function MyController($scope) {
    $scope.contacts = [];
}

datasource changed -> function () {
    MyController.set('contacts', 'value'); // change angular scope property
}

3 ответов


посмотрите на сокет.угловое обслуживание io:

angular.module('app')
  .factory('socket', ['$rootScope', function ($rootScope) {

    var socket = io.connect();

    return {
      on: function (eventName, callback) {
        socket.on(eventName, function () {  
          var args = arguments;
          $rootScope.$apply(function () {
            callback.apply(socket, args);
          });
        });
      },
      emit: function (eventName, data, callback) {
        socket.emit(eventName, data, function () {
          var args = arguments;
          $rootScope.$apply(function () {
            if (callback) {
              callback.apply(socket, args);
            }
          });
        })
      }
    };

  }]);

и контроллер, использующий его:

angular.module('app')
  .controller('Controller', ['$scope', 'socket', function ($scope, socket) {

    socket.emit('register')

    socket.on('register', function (data) {
        $scope.data = data;
    });

}]);

просто сделайте это, как показано ниже

 socket.onmessage = function (event) {
     scope.$apply(function(){
       // modify scope values here 
     }
    };

Ну, отмеченный ответ, безусловно, не является "простым способом", как просил OP. Вот гораздо более простое решение.

получить область, где вы хотите, в вашем собственном коде JavaScript:

var scope = angular.element($("#elementID")).scope();

изменить значение в угловых $scope переменная, но из вашего внешнего JavaScript:

scope.$apply(function() {
    scope.yourArrayForExample.push({name: 'New, external value'});
});

здесь JSFiddle.