jac*_*uac 16 angularjs angular-ui angular-ui-router
我是AngularUI路由器的新手,并希望将它用于以下场景:
所有页面共有的布局包括顶部导航栏,其中包含右侧带有按钮的菜单,以及填充下方空间的内容部分.该页面有几个页面,我映射到UI路由器状态(第1页,第2页,...).每个页面都有自己的菜单项和自己的内容.该菜单需要与内容共享范围,因为它们交互(例如保存按钮提交的内容形式,它应该只如果表单有效启用).
HTML大致如下所示:
<body>
<nav class="...">
<h1>my site</h1>
<div>MENU SHOULD GO HERE</div>
</nav>
<div class="row">
<div class="column ...">
CONTENT SHOULD GO HERE
</div>
</div>
</body>
Run Code Online (Sandbox Code Playgroud)
现在,我正在为每个州使用两个并行视图和两个控制器.但是这样,两个示波器/控制器无法交互.
那你怎么做到这一点?
che*_*ard 22
$ scope不是模型,它是模型的引用,介于数据和视图之间.如果两个或更多控制器中的$ scope需要共享一个模型/状态/数据,则通过注册角度服务来使用单个对象实例.可以将一个服务/工厂注入到任意数量的控制器中,然后一切都可以解决这个问题的真相.
下面是一个工厂的演示,它将navbar&body中的$ scope与ui-router连接起来http://plnkr.co/edit/P2UudS?p=preview(仅限左侧标签)
ui-router(viewC是导航栏):
$stateProvider
.state('left', {
url: "/",
views: {
"viewA": {
controller: 'LeftTabACtrl',
template: 'Left Tab, index.viewA <br>' +
'<input type="checkbox" ng-model="selected2.data" />' +
'<pre>selected2.data: {{selected2.data}}</pre>'
},
{...},
"viewC": {
controller: 'NavbarCtrl',
template: '<span>Left Tab, index.viewC <div ui-view="viewC.list"></div>' +
'<input type="checkbox" ng-model="selected.data" />' +
'<pre>selected.data: {{selected.data}}</pre></span>'
}
}
})
Run Code Online (Sandbox Code Playgroud)
工厂和控制器:
app.factory('uiFieldState', function () {
return {uiObject: {data: null}}
});
app.controller('NavbarCtrl', ['$scope', 'uiFieldState', '$stateParams', '$state',
function($scope, uiFieldState, $stateParams, $state) {
$scope.selected = uiFieldState.uiObject;
}
]);
app.controller('LeftTabACtrl', ['$scope', 'uiFieldState', '$stateParams', '$state',
function($scope, uiFieldState, $stateParams, $state) {
$scope.selected2 = uiFieldState.uiObject;
}
]);
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,工厂对象{uiObject: {data: null}}
注入到控制器uiFieldState
和那么它只是$scope.selected = uiFieldState.uiObject;
为工厂连接范围ng-model="selected.data"
.`
你应该使用:
$on and $emit
Run Code Online (Sandbox Code Playgroud)
发送控制器,用于发送数据.
angular.module('MyApp').controller('MyController', ['$scope', '$rootScope', function ($scope, $rootScope){
$rootScope.$emit('SomeEvent', data);
}]);
Run Code Online (Sandbox Code Playgroud)
一个如何实现$ rootScope安全方式的示例,以便在使用后销毁和修复内容:
angular
.module('MyApp')
.config(['$provide', function($provide){
$provide.decorator('$rootScope', ['$delegate', function($delegate){
Object.defineProperty($delegate.constructor.prototype, '$onRootScope', {
value: function(name, listener){
var unsubscribe = $delegate.$on(name, listener);
this.$on('$destroy', unsubscribe);
},
enumerable: false
});
return $delegate;
}]);
}]);
Run Code Online (Sandbox Code Playgroud)
并且控制器具有应该处理的数据.
angular.module('MyApp')
.controller('MySecondController', ['$scope', function MyController($scope) {
$scope.$onRootScope('SomeEvent', function(event, data){
console.log(data);
});
}
]);
Run Code Online (Sandbox Code Playgroud)
您可以传入$ rootScope而不是使用我们在配置中定义的$ scopes方法$ onRootScope.但是,这不是使用$ emit和$ onRootScope的推荐方法.
您可以使用$ broadcast,而不是使用$ emit.但是,随着应用程序的增长,这会给您带来非常大的性能问题.因为它通过所有控制器冒泡数据.
如果您的控制器是父母和孩子,他们不必使用$ rootScope.
以下是$ emit和$ broadcast:jsFiddle之间差异的示例
他们的确是性能差异:
归档时间: |
|
查看次数: |
11676 次 |
最近记录: |