Angular,设置回调函数,用于在工厂和控制器之间进行更新

时间:2015-03-09 21:00:44

标签: javascript angularjs

我不确定我是否已经完全理解了这个想法 - 但我会尽力清楚地描述我在这里要做的事情。

我有一个工厂可以为我更改和解析URL,因此我可以将params传递给控制器​​以供使用(存储在url中)。这有点让我可以为用户保存状态,他们可以通过复制URL(将其发送给他们的朋友或将其加入书签或w / e)来共享它。

我正在尝试设置一个侦听locationChangeSuccess的工厂(或服务) - 这样如果用户mofies url并按Enter键,它将刷新控制器中的范围。所以这就是我所拥有的:

   .factory("urlFactory", function($location, freshUrl, StateString){
     //request to change new url
    requestObj.requestState = function(moduleName, stateName, startVar){

    }

    //request item from url, via your module and state name
    requestObj.parseState = function(moduleName, stateName){

   }

我放弃了中心(如果需要我很乐意链接),但那些只是为我获取并设置了网址。

所以在控制器中我做了类似

的事情
 $scope.mod2m3 = urlFactory.parseState("module2", "mod3");
$scope.mod2m4 = urlFactory.parseState("module2", "mod4");

因此,当他们登陆页面时,他们会拉动他们的状态。这非常有效。但是,现在我试图解决一些可能用户修改网址的边缘情况。

所以我可以用

轻松地抓住它
 .factory("urlWatcher", function($location, $scope){
    var urlWatcher = {};
     $scope.$on('$locationChangeSuccess', function(event) {
            console.log("Asdsa");
       });

     return urlWatcher
});

然而,我正在努力的方法是尝试确定一种方式,当它触发时,它会将新值连接到控制器中的范围。有人向我建议在解析(set)函数中进行某种回调,但我正在努力解决这个问题。如果我能为这个工厂/服务设置一种方法,当它更改到正确的位置时重新发送新值,那将是非常酷的。回调听起来不错,但我不知道如何正确配置。

最简单的方法就是做一个

 $scope.$on('$locationChangeSuccess', function(event) {
            console.log("Asdsa");
       });

在每个控制器中并手动绑定到每个范围,但我试图使其尽可能模块化(这也是locationchangesuccess上的大量观察者)。如果我能想出一个干净的方式来设置服务/工厂一次听,并且在更改时找到正确的模块/控制器并更改值,那将是太棒了。

我似乎无法想出一条明确的路线,所以我对这个问题的任何见解都非常感激。非常感谢您的阅读!

2 个答案:

答案 0 :(得分:3)

如果您想要的是发布/订阅体系结构,其中发布是全局的,订阅与Angular范围具有相同的生命周期......那么Angular事件 您正在寻找的内容。没有必要设置一个带有回调和whatnut的 ad hoc 通信系统,这只会部分地重新发明事件。

但是,如果您希望使语义更加明显/增加灵活性,您可以在服务中将一次收听$locationChangeSuccess并广播自定义事件。

$rootScope.$on("$locationChangeSuccess", function (event) {
  $rootScope.$broadcast('myCustomeEvent', {message: "Guys, time to refresh!"});
});

然后在相关的每个范围内收听此事件。

$scope.$on('myCustomeEvent', function (event) {
  console.log("Asdsa");
});

如果通过各种方式设置监听重复,请将其分解为函数,例如,您可以将其放入服务中:

myApp.factory('someFactory', [function () {
  return {
    listenToLogAsdsa: function (scope) {
      scope.$on('myCustomeEvent', function (event) {
        console.log("Asdsa");
      });
    }  
  };
}]);

然后你必须在你的控制器中写下:

someFactory.listenToLogAsdsa($scope);

答案 1 :(得分:0)

您可以将范围中的变量分配给工厂中的对象,这样就可以将其绑定到引用而不是值。然后,在HTML中绑定对DOM的引用。然后urlFactory.parseState()应该将结果保存到所述对象,并​​返回保存它的密钥。
例如:
在urlFactory:

requestObj.parseState = function(moduleName, stateName){
var key = moduleName+stateName;
this.urlContainer[key] = "www.example.com";
return key;

   }

在控制器中:

$scope.urls = urlFactory.urlContainer;
$scope.mod2m3 = urlFactory.parseState("module2", "mod3");

在您的HTML中:

{{urls[mod2m3]}}

这样," urls"绑定到一个引用,其中angular监视更改,并且每当您更改URL [mod2m3]时,它都会影响DOM。
您也可以通过观察它们来对范围变量的变化作出反应:

 $scope.$watch('urls', function() {
       //do something
   });

注意:由于这是一个对象,您可能需要使用$ watchCollection而不是$ watch。