1

Скажем у меня есть следующий завод:Угловое значение часового завода

app.factory("categoryFactory", function (api, $http, $q) {  
    var selected = null; 
    var categoryList = []; 
    return { 
     getList: function() { 
      var d = $q.defer(); 
      if(categoryList.length <= 0){ 
       $http.get(api.getUrl('categoryStructure', null)) 
        .success(function (response) { 
         categoryList = response; 
         d.resolve(categoryList); 
        }); 
      } 
      else 
      { 
       d.resolve(categoryList) 
      } 
      return d.promise; 
     }, 
     setSelected: function (category) { 
      selected = category; 
     }, 
     getSelected: function() { 
      return selected; 
     } 
    }  
}); 

теперь у меня есть два контроллера, используя этот завод в то же время. Из-за этого оба контроллера должен быть уведомлен при обновлении для этого я попытался следующее:

app.controller('DashboardController', ['$http', '$scope', '$sessionStorage', '$log', 'Session', 'api','categoryFactory', function ($http, $scope, $sessionStorage, $log, Session, api, categoryFactory) { 

    $scope.selectedCategory = categoryFactory.getSelected(); 

}]); 

В то время как мой другой контроллер выглядит следующим образом:

app.controller('NavController', ['$http', '$scope', '$sessionStorage', '$log', 'Session', 'api', 'FileUploader', 'categoryFactory', function ($http, $scope, $sessionStorage, $log, Session, api, FileUploader, categoryFactory) { 
    $scope.categories = []; 

    categoryFactory.getList().then(function (response) { 
     $scope.categories = response; 
    }); 
    $scope.selectCategory = function (category) { 
     categoryFactory.setSelected(category); 
    } 

}]); 

как всегда, когда NavController изменил значение это было не изменен в DashboardController

Мой вопрос в том, как я могу либо watch, либо другим способом получить уведомление при изменении значения?

ответ

2

Вы можете использовать observer шаблон, например, так:

app.factory("categoryFactory", function (api, $http, $q) { 
    // the list of callbacks to call when something changes 
    var observerCallbacks = []; 

    // ... 

    function notifyObservers() { 
     angular.forEach(observerCallbacks, function(callback) { 
      callback(); 
     }); 
    } 

    return { 
     setSelected: function (category) { 
      selected = category; 
      // notify the observers after you change the value 
      notifyObservers(); 
     }, 
     registerObserver: function(callback) { 
      observerCallbacks.push(callback); 
     } 
    }  
}); 

, а затем в контроллерах:

app.controller('NavController', ['$http', '$scope', '$sessionStorage', '$log', 'Session', 'api', 'FileUploader', 'categoryFactory', function ($http, $scope, $sessionStorage, $log, Session, api, FileUploader, categoryFactory) { 
    // ... 

    // init 
    (function() { 
     categoryFactory.registerObserver(function() { 
      categoryFactory.getList().then(function (response) { 
       $scope.categories = response; 
      }); 
     }); 
    })(); 

}]); 

Таким образом, в любое время setSelected называется, это вызывает каждый обратный вызов, что вы» ve зарегистрирован в observerCallbacks. Вы можете зарегистрировать их с любого контроллера, так как фабрики являются синглонами, и они всегда будут в курсе.

Edit: просто хочу добавить, что я, возможно, поставить notifyObservers() вызов в неправильной области (в настоящее время в setSelected) и что я могу помещать неправильный вызов обновления в контроллере (в настоящее время getList), но архитектура остается тоже самое. В registerObserver, положить все, что вы хотите делать, когда значения обновляются и где бы вы внести изменения, которые вы хотите наблюдателей знать о вызове notifyObservers()

+0

Hey tom работал как шарм, однако вам нужно удалить «это» из вашей функции registerObserver –

+0

@MarcRasmussen ah, отметил ... done – Tom

+0

Отличный ответ! Просто FYI: дополнительный $ scope. В моем случае был необходим вызов $ apply(), чтобы обновить мои переменные! :) – luQ

1

Вы можете следовать dot rule здесь, так что прототипичное наследство получит последовало.

В принципе, у вас должен быть один объект внутри вашего сервиса, который будет иметь переменную selected, и избавится от метода getSelected.

завод

app.factory("categoryFactory", function(api, $http, $q) { 
    var categoryFactory = {}; 
    categoryFactory.getList = function() { 
     var d = $q.defer(); 
     if (categoryList.length <= 0) { 
      $http.get(api.getUrl('categoryStructure', null)) 
       .success(function(response) { 
        categoryList = response; 
        d.resolve(categoryList); 
       }); 
     } else { 
      d.resolve(categoryList) 
     } 
     return d.promise; 
    } 
    categoryFactory.setSelected = function(category) { 
     categoryFactory.data.selected = category; 
    } 
    categoryFactory.data = { 
     selected: null 
    } 
    return categoryFactory; 
}); 

Контроллер

app.controller('DashboardController', ['$http', '$scope', '$sessionStorage', '$log', 'Session', 'api', 'categoryFactory', 
    function($http, $scope, $sessionStorage, $log, Session, api, categoryFactory) { 
     //this will provide you binding without watcher 
     $scope.selection = categoryFactory.data; 
    } 
]); 

И затем использовать {{selection.selected}} на HTML часть будет обновлять значение, когда изменения будут происходить в выборе.

+0

привет, спасибо за ваш ответ. К сожалению, это не работает: S значение не изменяется в контроллере после изменения значения на заводе –

+0

@MarcRasmussen посмотреть на мое обновление должно работать сейчас –

+0

сделал youvlooked at my edit ?? –

Смежные вопросы