【发布时间】:2016-03-29 02:06:14
【问题描述】:
在我的网站上,我有一个导航栏组件,我想为最终加载的每个 ng-view 进行自定义。目前我这样做如下。我有一个导航栏本身的 NavCtrl,我的 ng-view 指令位于此控制器的范围之外。我使用导航栏服务来更改/覆盖导航栏中的功能,例如,我的每个视图都需要覆盖导航栏的保存按钮的单击处理程序。 NavbarService 具有设置保存功能的钩子。在 NavCtrl 中 $scope.save = NavbarService.save
var app = angular.module('myApp', ['ngRoute', 'ngResource']);
app.config(function($routeProvider) {
$routeProvider.when('/world', {templateUrl : 'world.html', controller : 'WorldCtrl'}).otherwise({templateUrl : 'hello.html', controller : 'HelloCtrl'});
});
app.service('NavbarService', function() {
var message = 'Save button not clicked yet',
saveFunction = function() {
this.setMessage('Default save called');
};
this.save = function() {
_saveFunction();
};
this.setSaveFunction = function(funct) {
_saveFunction = funct;
};
this.setMessage = function(newMessage) {
message = newMessage;
};
this.getMessage = function() {
return message;
}
});
app.controller('NavCtrl', function($scope, $location, NavbarService) {
$scope.message = NavbarService.getMessage();
$scope.save = NavbarService.save;
$scope.world = function() {
$location.path('/world');
};
$scope.hello = function() {
$location.path('/hello');
};
$scope.$watch(NavbarService.getMessage, function(newValue) {
$scope.message = newValue;
});
});
app.controller('HelloCtrl', function($scope, NavbarService) {
$scope.init = function() {
NavbarService.setSaveFunction(function() {
NavbarService.setMessage('Save method called from the HelloCtrl');
});
};
});
app.controller('WorldCtrl', function($scope, NavbarService) {
$scope.init = function() {
NavbarService.setSaveFunction(function() {
NavbarService.setMessage('Save method called from the WorldCtrl');
});
};
});
<html lang="en">
<head>
<title>My App</title>
</head>
<body ng-app="myApp">
<nav ng-controller="NavCtrl">
<button ng-click="save()">Save</button>
<button ng-click="world()">Go to world</button>
<button ng-click="hello()">Go to hello</button>
<pre>{{message}}</pre>
</nav>
<div ng-view onload="init()"></div>
<script type="text/ng-template" id="hello.html">
<h2>Active view is Hello</h2>
</script>
<script type="text/ng-template" id="world.html">
<h2>Active view is World</h2>
</script>
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular-route.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular-resource.js"></script>
</body>
</html>
我想知道我是否让这太复杂了。我认为只需将 ng-view 指令嵌套在 NavCtrl 的范围内即可实现相同的目的。这样我就可以在每个视图控制器中覆盖 $scope.save。
但大多数文档都指出,服务是跨控制器共享资源的首选方式。一种方式比另一种更好吗?为什么?
请指教。谢谢。
【问题讨论】:
-
这里有几个反模式。你永远不应该从控制器/服务中修改 DOM。它们仅用于管理数据/状态。 #message 应该是模板的一部分,并通过模板更改进行更改,或者有自己的控制器来监听路由并修改驱动消息的范围属性。
-
感谢您的评论。我只需要演示“保存”按钮在活动视图控制器上执行保存方法。 #message 只是为了显示日志。换句话说,又快又脏。我已经修改了我的代码 sn-p 以消除您指出的违规行为。
-
我认为这个问题应该转移到 codereview 网站,因为它提供了完整的工作代码并要求审查。
标签: angularjs angularjs-scope angular-services