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

Angular, setting up a callback function for updating between factory and controller

本文关键字:工厂 用于 控制器 更新 之间 函数 回调 设置 一个 Angular      更新时间:2023-09-26

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

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

我正在尝试设置一个侦听 locationChangeSuccess 的工厂(或服务) - 这样,如果用户移动 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){
   }

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

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

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

因此,当他们登陆页面时,他们拉动了他们的状态。这很好用。但是,现在我正在尝试解决一些边缘情况,其中用户可能会修改 url。

所以我可以很容易地抓住它

 .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");
       });

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

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

如果你想要的是一个发布/订阅架构,其中发布是全局的,订阅的生命周期与 Angular 范围相同......那么角度事件就是你要找的。没有必要建立一个带有回调之类的临时通信系统,那只会部分地重塑事件。

但是,如果要使语义更明显/增加灵活性,则可以侦听一次以在服务中$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);

您可以将作用域中的变量分配给工厂中的对象,这样它就会绑定到引用而不是值。urlFactory.parseState() 应该将结果保存到所述对象,并返回保存它的键。
例如:
在网址工厂中:

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"被绑定到一个引用,该引用的角度监视更改,并且每当您更改urls[mod2m3]时,它都会影响DOM。
您也可以通过观察作用域变量的变化来对它们做出反应:

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

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