Plnkr: https://plnkr.co/edit/Brmcxd2LjGVJ6DXwuJtF?p=preview
架构:
$login
-> $container
(包含$dashboard
和$feed
), dashboard
包含:$tickers
、$tags
、$viewHeader
和$socialMedia
组件。
目标:
tags
需要与viewHeader
和socialMedia
状态进行通信并发送一个标签对象。
期望结果:
在Login后,从标签列表中选择一个按钮应该会将该tag
发送到ViewHeader和SocialMedia的状态/组件中。
结果:
在Login后,从标签列表中选择一个按钮并转到$state dashboard
时,ViewHeader和SocialMedia的状态会刷新,但视图模型变量{{ term }}
在任何组件中都不会更新为相应的标签。
设计说明:
我试图通过状态、组件、同级组件和视图的混合使用来解决一个问题,即应用程序中的每个组件在任何状态更改时都会刷新/重新初始化。 $state.go('dashboard'...
这不是理想的情况,我希望只有需要刷新的组件才会刷新。
例如:当我选择一个Ticker或Tag时,我不希望Feed组件每次都刷新。但是用户应该能够在Feed组件中执行操作并更新所有其他组件。
这就是为什么我创建了一个container
状态来容纳dashboard
和feed
状态。最初,我把所有东西都放在dashboard
状态中,每当$state.go('dashboard'
发生时,feed
组件也会刷新。如果有更好的方法来解决这个问题,请告诉我!:)
附注: 开始学习使用ui-router进行状态管理,以去除对$rootScope的依赖。到目前为止,我的真正应用程序更加稳定,但有一个讨厌的特性,即每个组件都会刷新/重新初始化。
在下面的截图中,我可以清楚地看到正确的tag
被传递到了正确的$states中,但是{{ term }}
没有更新。
代码片段(完整代码在Plnkr中)
app.container.html(容器状态)
<div>
<dashboard-module></dashboard-module>
<feed-module></feed-module>
<!--<div ui-view="dashboard"></div>-->
<!--<div ui-view="feed"></div>-->
</div>
仪表板页面 (仪表板状态)
<div class="jumbotron text-center">
<h1>The Dashboard</h1>
</div>
<div class="row">
<tickers-module></tickers-module>
<!-- Tags component goes here -->
<div ui-view></div>
<view-module></view-module>
<social-module></social-module>
</div>
我使用<div ui-view>
来加载标签状态的原因是这是目前初始化标签模块并从股票组件显示标签列表的唯一方法。
股票组件控制器:
tickers.component('tickersModule', {
templateUrl: 'tickers-module-template.html',
controller: function($scope, $state) {
console.log('Tickers component', $state.params);
$scope.tickers = [
{ id: 1, ticker: 'AAPL' },
{ id: 2, ticker: 'GOOG' },
{ id: 3, ticker: 'TWTR' }
];
$state.go('tags', { ticker: $scope.tickers[0] }); // <---
$scope.clickTicker = function(ticker) {
$state.go('tags', { ticker: ticker });
}
}
^ 上面的代码允许标签状态加载标签组件元素并根据ticker状态连接标签列表。
var tags = angular.module('tags', ['ui.router'])
tags.config(function($stateProvider) {
const tags = {
parent: 'container',
name: 'tags',
url: '/tags',
params: {
ticker: {}
},
template: '<tags-module></tags-module>',
controller: function($scope, $state) {
console.log('Tags state', $state.params);
}
}
$stateProvider.state(tags);
})
tags.component('tagsModule', {
templateUrl: 'tags-module-template.html',
controller: function($scope, $state) {
console.log('Tags component', $state.params);
const tags_model = [
{
ticker: 'AAPL',
tags : [{ id: 1, term: 'iPhone 7' }, { id: 2, term: 'iPhone 8' }, { id: 3, term: 'Tim Cook' }]
},
{
ticker: 'GOOG',
tags : [{ id: 4, term: 'Pixel' }, { id: 5, term: 'Pixel XL' }, { id: 6, term: 'Chrome Book' }]
},
{
ticker: 'TWTR',
tags : [{ id: 7, term: 'tweet' }, { id: 8, term: 'retweet' }, { id: 9, term: 'moments' }]
}
];
function matchTags(ticker, model) {
return model.filter(function(obj){
if (obj.ticker === ticker) { return obj; }
});
}
$state.params.ticker = $state.params.ticker || {};
$scope.tags_model = matchTags($state.params.ticker.ticker, tags_model)[0];
$scope.clickTag = function(tag) {
console.log(' Tag clicked', $state);
$state.go('dashboard', { tag: tag });
}
}
});
标签列表中的点击功能:
$scope.clickTag = function(tag) {
console.log(' Tag clicked', $state);
$state.go('dashboard', { tag: tag });
}
社交媒体控制器:
social.component('socialModule', {
templateUrl: 'social-module-template.html',
controller: function($scope, $state) {
console.log('Social component', $state.params);
$scope.term = $state.params.tag.term;
}
});
viewHeader控制器:
view.component('viewModule', {
templateUrl: 'view-module-template.html',
controller: function($scope, $state) {
console.log('View component', $state.params);
$scope.term = $state.params.tag.term;
}
});
组件奇怪的重复
我注意到这个问题,当我点击标签并进入social.component后发现。看起来仪表板组件在瞬间被重新渲染,代替了标签组件: