angular 如何在其他地方处理服务更改?
How angular service changes can be handled in somewhere else?
AngularJS 中的常见做法是制作和使用自定义服务进行 DOM 操作并在 UI 的不同部分共享相同的功能我的问题也与本案例如下:
我的应用程序中有一个侧边栏组件和一个用于在单击时最小化侧边栏的按钮,但问题是它们的控制器不同所以我在同一个模块中创建了一个名为 sidebarService
的服务并注入了这个服务进入两个控制器,但是当服务中的数据通过控制器的事件发生变化时,我无法在另一个控制器中处理它,所以如何做到这一点:
app-module.js
(function() {
'use strict';
var app = angular.module('app', []);
});
边栏-service.js
(function() {
'use strict';
angular.module('app')
.factory('sidebarService', function() {
var showClass = false;
return {
toggle: function() {
showClass = !showClass;
},
isClassShown: function() {
return showClass;
}
};
});
});
app-controller.js
(function() {
'use strict';
angular.module('app')
.controller('App', ['sidebarService', function(sidebarService) {
var appVm = this;
appVm.isClassShown = function() {
return sidebarService.isClassShown();
};
}]);
});
导航栏-controller.js
(function() {
'use strict';
angular.module('app')
.controller('Navbar', ['sidebarService', function(sidebarService) {
var navbarVm = this;
navbarVm.toggleSidebar = function() {
sidebarService.toggle();
};
}]);
})();
index.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<title>My App</title>
<!-- ... -->
</head>
<body ng-controller="App as app">
<ul ng-controller="Navbar as navbar">
<li>
<a href="#" ng-click="navbar.toggleSidebar()">Toggle Sidebar</a>
</li>
<!-- ... -->
</ul>
<div class="sidebar" ng-class="{mini:app.isClassShown()}">
<!-- ... -->
</div>
</body>
</html>
嗯,有两种方法:
解决方案 1:非常简单且同时也是典型的 angular 解决方案:您可以使用 $scope.$watch
来跟踪来自控制器的值。因此,在您的情况下,您需要向每个 $scope
添加您想要跟踪以下观察者的值:
$scope.$watch(function() { return sidebarService.isClassShown() }, function(newValue, oldValue) {
console.log(newValue, oldValue);
});
换句话说,在您的应用程序控制器中:
(function() {
'use strict';
angular.module('app')
.controller('App', ['$scope', 'sidebarService', function($scope, sidebarService) {
var appVm = this;
appVm.isClassShown = function() {
return sidebarService.isClassShown();
};
$scope.$watch(function() { return sidebarService.isClassShown() }, function(newValue, oldValue) {
console.log('changed', newValue, oldValue);
});
}]);
});
解决方案 2:抛出 angular 事件并监听此事件:使用 angular $emit 函数发出自定义事件。也可以使用第三方库来引发事件,我更喜欢它而不是标准 angular 事件系统。
使用父作用域的 属性 而 AngularJS 作用域使用原型继承概念然后使用父作用域属性 将在子作用域中可用,但要确保从子作用域进行更改并在父作用域中进行更改,请使用 JavaScript 基于对象的作用域属性。
有关此主题的更多信息,您可以阅读 here。
所以根据我的解释和建议做如下:
app-controller.js
(function() {
'use strict';
angular.module('app')
.controller('App', ['$scope', function($scope) {
$scope.someObj = {
sidebarClass: false
};
}]);
});
index.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<title>My App</title>
<!-- ... -->
</head>
<body ng-controller="App as app">
<ul ng-controller="Navbar as navbar">
<li>
<a href="#" ng-click="someObj.sidebarClass = !someObj.sidebarClass">Toggle Sidebar</a>
</li>
<!-- ... -->
</ul>
<div class="sidebar" ng-class="{mini:someObj.sidebarClass}">
<!-- ... -->
</div>
</body>
</html>
AngularJS 中的常见做法是制作和使用自定义服务进行 DOM 操作并在 UI 的不同部分共享相同的功能我的问题也与本案例如下:
我的应用程序中有一个侧边栏组件和一个用于在单击时最小化侧边栏的按钮,但问题是它们的控制器不同所以我在同一个模块中创建了一个名为 sidebarService
的服务并注入了这个服务进入两个控制器,但是当服务中的数据通过控制器的事件发生变化时,我无法在另一个控制器中处理它,所以如何做到这一点:
app-module.js
(function() {
'use strict';
var app = angular.module('app', []);
});
边栏-service.js
(function() {
'use strict';
angular.module('app')
.factory('sidebarService', function() {
var showClass = false;
return {
toggle: function() {
showClass = !showClass;
},
isClassShown: function() {
return showClass;
}
};
});
});
app-controller.js
(function() {
'use strict';
angular.module('app')
.controller('App', ['sidebarService', function(sidebarService) {
var appVm = this;
appVm.isClassShown = function() {
return sidebarService.isClassShown();
};
}]);
});
导航栏-controller.js
(function() {
'use strict';
angular.module('app')
.controller('Navbar', ['sidebarService', function(sidebarService) {
var navbarVm = this;
navbarVm.toggleSidebar = function() {
sidebarService.toggle();
};
}]);
})();
index.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<title>My App</title>
<!-- ... -->
</head>
<body ng-controller="App as app">
<ul ng-controller="Navbar as navbar">
<li>
<a href="#" ng-click="navbar.toggleSidebar()">Toggle Sidebar</a>
</li>
<!-- ... -->
</ul>
<div class="sidebar" ng-class="{mini:app.isClassShown()}">
<!-- ... -->
</div>
</body>
</html>
嗯,有两种方法:
解决方案 1:非常简单且同时也是典型的 angular 解决方案:您可以使用 $scope.$watch
来跟踪来自控制器的值。因此,在您的情况下,您需要向每个 $scope
添加您想要跟踪以下观察者的值:
$scope.$watch(function() { return sidebarService.isClassShown() }, function(newValue, oldValue) {
console.log(newValue, oldValue);
});
换句话说,在您的应用程序控制器中:
(function() {
'use strict';
angular.module('app')
.controller('App', ['$scope', 'sidebarService', function($scope, sidebarService) {
var appVm = this;
appVm.isClassShown = function() {
return sidebarService.isClassShown();
};
$scope.$watch(function() { return sidebarService.isClassShown() }, function(newValue, oldValue) {
console.log('changed', newValue, oldValue);
});
}]);
});
解决方案 2:抛出 angular 事件并监听此事件:使用 angular $emit 函数发出自定义事件。也可以使用第三方库来引发事件,我更喜欢它而不是标准 angular 事件系统。
使用父作用域的 属性 而 AngularJS 作用域使用原型继承概念然后使用父作用域属性 将在子作用域中可用,但要确保从子作用域进行更改并在父作用域中进行更改,请使用 JavaScript 基于对象的作用域属性。
有关此主题的更多信息,您可以阅读 here。
所以根据我的解释和建议做如下:
app-controller.js
(function() {
'use strict';
angular.module('app')
.controller('App', ['$scope', function($scope) {
$scope.someObj = {
sidebarClass: false
};
}]);
});
index.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<title>My App</title>
<!-- ... -->
</head>
<body ng-controller="App as app">
<ul ng-controller="Navbar as navbar">
<li>
<a href="#" ng-click="someObj.sidebarClass = !someObj.sidebarClass">Toggle Sidebar</a>
</li>
<!-- ... -->
</ul>
<div class="sidebar" ng-class="{mini:someObj.sidebarClass}">
<!-- ... -->
</div>
</body>
</html>