javascript – 如何将$state变量传递给另外两个兄弟的$状态?
作者:互联网
Plnkr:https://plnkr.co/edit/Brmcxd2LjGVJ6DXwuJtF?p=preview
建筑:
$login – > $container(包含$dashboard和$feed),仪表板包含:$tickers,$tags,$viewHeader和$socialMedia组件.
目标:
标签需要通信并将标签对象发送到viewHeader和socialMedia状态.
预期:
登录后,选择标签列表中的按钮应将该标签发送到ViewHeader和SocialMedia状态/组件.
结果:
登录后,选择标签中的按钮并转到$state仪表板,查看ViewHeader和SocialMedia刷新的$状态,但视图模型变量{{term}}不会使用任一组件中的相应标签进行更新.
设计说明:
我试图通过混合状态,组件,兄弟组件和视图来解决的问题是,当任何状态发生变化时,应用程序中的每个组件都会刷新/重新启动. $state.go( ‘仪表盘’ ……
这并不理想,我想要的是确保只需要刷新,刷新的组件.
IE:当我选择Ticker或Tag时,我不希望Feed组件每次都刷新.但是,用户应该能够在Feed组件中执行操作,并且它将更新所有其他组件.
这就是我创建容器状态以保持仪表板和进给状态的原因.最初我把所有东西都放在仪表板状态,随时$state.go(‘dashboard’发生了,feed组件也会刷新.如果有更好的方法来解决这个问题lmk!:)
PS:开始使用ui-router了解状态管理,以消除对$rootScope的依赖.到目前为止,我的真实应用程序更加稳定,但是具有每个组件刷新/重新启动的烦人功能.
在下面的屏幕截图中,我可以清楚地看到正确的标记正在传递到正确的$状态,但{{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>
dashboard.html(仪表板状态)
<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 });
}
}
^< ---上面允许标签状态加载标签组件元素并根据自动收报机的状态连接标签列表
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 });
}
socialMedia控制器:
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之后,就注意到了这一点.看起来仪表板组件正在重新呈现以代替标签组件一瞬间:
更新,通过在标签中添加{refresh:true}到$state.go来解决此问题.但请注意,这仍然无法解决我的原始任务,这会阻止feed.component刷新.因此最终将使用服务.
https://plnkr.co/edit/R0iwJznOgEwOL7AtU5wP?p=preview
解决方法:
我已经更新了你的plunker
https://plnkr.co/edit/ywyH7wOmR6loNiAkH9Yb?p=preview
解决方案非常简单.而不是使用$state在依赖注入中使用$stateParams,这是一个单例,所以如果你像我在更新的plunker中那样引用它:
$scope.params = $stateParams
然后是显示值
{{params.ticker.ticker}}
将以$2方式绑定到$stateParams,并在每次更改状态时进行相应更新
– -编辑 – –
我通过服务添加了另一个解决方案
https://plnkr.co/edit/oQNAHv7tAS8LR9njOUAX?p=preview
.service('awesomeTag', function($rootScope){
var self = this;
$rootScope.$on('$stateChangeSuccess', function(_event, _toState, toParams){
self.tag = toParams.ticker.ticker
})
})
标签:javascript,angularjs,angular-ui-router,routing,state-management 来源: https://codeday.me/bug/20190622/1265690.html