Plnkr:https://plnkr.co/edit/Brmcxd2LjGVJ6DXwuJtF?p=preview

建筑:
$login-> $container(包含$dashboard$feed),dashboard包含:$tickers$tags$viewHeader$socialMedia组件。

目标:
tags需要进行通信并将标签对象发送到viewHeadersocialMedia状态。

预期:

登录后,在“标签”列表中选择一个按钮,应将该tag发送到ViewHeader和SocialMedia状态/组件中。

结果:

登录后,在“标签”中选择一个按钮,然后转到$ state dashboard,刷新ViewHeader和SocialMedia的$ states,但是 View 模型变量{{ term }}不会在任何一个组件中使用适当的标签进行更新。

javascript - 如何将$ state变量传递给其他2个同级$ state?-LMLPHP

设计说明:

我试图通过混合状态,组件,同级组件和 View 来解决的问题是,当任何状态发生变化时,应用程序中的每个组件始终会刷新/重新启动Init。 $state.go('dashboard'...
这不是理想的选择,我想要确保仅需要刷新的组件才能刷新。

IE:当我选择一个收盘机标记时,我不希望 Feed 组件每次刷新一次。但是,用户应该能够在 Feed 组件中执行操作,它将更新所有其他组件。

这就是为什么我创建了container状态以同时包含dashboardfeed状态的原因。最初,我所有内容都处于dashboard状态,并且每当$state.go('dashboard'发生时,feed组件也会刷新。如果有更好的方法可以解决lmk这个问题! :)

PS:开始学习使用ui-router消除对$ rootScope的依赖的状态管理。到目前为止,我的真实应用程序更加稳定,但是具有烦人的功能,每个组件都会刷新/重新启动。

javascript - 如何将$ state变量传递给其他2个同级$ state?-LMLPHP

在下面的屏幕截图中,我可以清楚地看到正确的tag被传递到了正确的$ states,但是{{ term }}并未更新。

javascript - 如何将$ state变量传递给其他2个同级$ state?-LMLPHP

javascript - 如何将$ state变量传递给其他2个同级$ state?-LMLPHP

代码段(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组件 Controller :
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 Controller :
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 Controller :
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内部之后。似乎仪表板组件正在重新渲染以代替标签组件,瞬间:

javascript - 如何将$ state变量传递给其他2个同级$ state?-LMLPHP

已更新,通过在标签的$ state.go中添加{ refresh: true }解决了这里的问题。但是请注意,这仍然不能解决我的原始任务,即阻止feed.component刷新。因此最终将使用服务。

https://plnkr.co/edit/R0iwJznOgEwOL7AtU5wP?p=preview

javascript - 如何将$ state变量传递给其他2个同级$ state?-LMLPHP

最佳答案

我已经更新了你的矮人

https://plnkr.co/edit/ywyH7wOmR6loNiAkH9Yb?p=preview

解决方案非常简单。而不是使用$state,而是在依赖项注入(inject)中使用$stateParams,这是一个单例,因此,如果像我在更新的插件中一样进行引用,则可以使用它:

$scope.params = $stateParams

然后显示值
{{params.ticker.ticker}}

将绑定(bind)到$ stateParams的2种方式,并在每次更改状态时相应地更新

- -编辑 - -

我通过服务添加了另一个解决方案
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
  })

})

07-24 09:44
查看更多