我不确定我是否已经完全理解了这个想法 - 但我会尽力清楚地描述我在这里要做的事情。
我有一个工厂可以为我更改和解析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上的大量观察者)。如果我能想出一个干净的方式来设置服务/工厂一次听,并且在更改时找到正确的模块/控制器并更改值,那将是太棒了。
我似乎无法想出一条明确的路线,所以我对这个问题的任何见解都非常感激。非常感谢您的阅读!
答案 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。