用于1个模块的ui-view复制来自另一个模块的内容

时间:2017-03-16 16:11:10

标签: javascript angularjs angular-ui-router

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

预期

login 之后,当您单击 Count 时,红色数字应在标签列表中更改并与“代码”列表中的数字相匹配,但Feed列表中不会发生任何事情

结果

login 之后,点击Tickers列表中的 Count ,红色数字会出现在Tags列表和Feed列表中。

enter image description here

完整的plnkr代码

var tickers = angular.module('tickers', ['ui.router'])

tickers.config(function($stateProvider) {

  const tickers = {
    name: 'tickers',
    url: '/tickers',
    parent: 'dashboard',
    templateUrl: '<p></p>'
  }

  $stateProvider
    .state(tickers);

})

tickers.component('tickersModule', {
  templateUrl: 'tickers-list.html',
  controller: function($scope, $state) {
    console.log('Tickers init', $state.params)

    $scope.counter = 0;

    $scope.increase = function() {
      $scope.counter++;
      $state.go('tags', { counter: $scope.counter }).then(function() {
      });
    }
  }
})



var tags = angular.module('tags', ['ui.router'])

tags.config(function($stateProvider) {

  const tags = {
    name: 'tags',
    url: '/tags',
    parent: 'dashboard',
    params: {
      counter: 0
    },
    template: '<p class="counter">{{ counter }}</p>',
    bindToController: true,
    controller: function($scope, $state) {
      console.log('tags state object', $state)
      $scope.counter = $state.params.counter;
    }
  }

  $stateProvider
    .state(tags);

})

tags.component('tagsModule', {
  templateUrl: 'tags-module-template.html',
  controller: function($scope, $state) {

  }
})


var feed = angular.module('feed', ['ui.router'])

feed.config(function($stateProvider) {

  const feed = {
    name: 'feed',
    url: '/feed',
    parent: 'dashboard',
    templateUrl: '<em>Feed items go here.</em>'
  }

  $stateProvider
    .state(feed);

})

feed.component('feedModule', {
  templateUrl: 'feed-module-template.html',
  controller: function($scope, $state) {
    console.log('Feed init', $state.params)

  }
})


var routerApp = angular.module('routerApp', ['ui.router', 'tickers', 'tags', 'feed']);

routerApp.config(function($stateProvider, $urlRouterProvider) {

    $urlRouterProvider.otherwise('/login');

    const login = {
      name: 'login',
      url: '/login',
      templateUrl: 'login.html',
      bindToController: true,
      controllerAs: 'l',
      controller: function($state) {
        this.login = function() {
          $state.go('dashboard', {})
        }
      }
    }

    const dashboard = {
      name: 'dashboard',
      url: '/dashboard',
      templateUrl: 'dashboard.html',
      controller: function($state) {
        console.log('Dashboard state init', $state)
      }
    }

    $stateProvider
        .state(login)
        .state(dashboard);

})
.run(['$rootScope', '$location', '$state',
function($rootScope, $location, $state) {
    $rootScope.$on("$stateChangeError", console.log.bind(console));
    $rootScope.$on('$stateChangeStart',
        function(event, toState, toParams, fromState, fromParams, options) {
            // console.log(' ')
            // console.log('toState', toState)
            // console.log('toParams', toParams)
            // console.log('fromState', fromState)
            // console.log('fromParams', fromParams)
            // console.log('options', options)
        });
}]);

tags-module-template.html

<div class="jumbotron text-center">
  <h2>Tags list</h2>
  <div ui-view></div>
</div>

feed-module-template.html

<div class="jumbotron text-center">
  <h2>Feed list</h2>
  <div ui-view></div>
</div>

与routerApp模块中的仪表板状态关联的dashboard.html。包含所有3个组件:

<div class="jumbotron text-center">
    <h1>The Dashboard</h1>
</div>

<div class="row">
  <tickers-module></tickers-module>
  <tags-module></tags-module>
  <feed-module></feed-module>
</div>

标签模块,状态配置和组件代码:

var tags = angular.module('tags', ['ui.router'])

tags.config(function($stateProvider) {

  const tags = {
    name: 'tags',
    url: '/tags',
    parent: 'dashboard',
    params: {
      counter: 0
    },
    template: '<p class="counter">{{ counter }}</p>',
    bindToController: true,
    controller: function($scope, $state) {
      console.log('tags state object', $state)
      $scope.counter = $state.params.counter;
    }
  }

  $stateProvider
    .state(tags);

})

tags.component('tagsModule', {
  templateUrl: 'tags-module-template.html',
  controller: function($scope, $state) {

  }
})

Feed模块,状态配置和组件代码

var feed = angular.module('feed', ['ui.router'])

feed.config(function($stateProvider) {

  const feed = {
    name: 'feed',
    url: '/feed',
    parent: 'dashboard',
    templateUrl: '<em>Feed items go here.</em>'
  }

  $stateProvider
    .state(feed);

})

feed.component('feedModule', {
  templateUrl: 'feed-module-template.html',
  controller: function($scope, $state) {
    console.log('Feed init', $state.params)

  }
})

2 个答案:

答案 0 :(得分:2)

以下是具有所需功能的Plunker link

在进入我的解决方案之前,让我们通过你的解决方案。

之所以按照你描述的方式工作的原因是因为ui-router正在做的是假设要做的事情:)。

即使您已尝试将模板加载到单独的模块中,但这并没有按照您的计划进行。加载dashboard状态后,所有组件也会加载。 tags-modulefeed-module同时更新的原因是因为其各自的模板中包含ui-view。因此,当您单击按钮并执行$state.go("tags"...时,您基本上已在其中包含tags属性的每个组件中加载了ui-view状态模板。

我提供的解决方案使用$rootScope.$emit$rootScope.$on来发送dand接收数据。我必须说你应该尽可能避免使用$ rootScope ,但为了简洁起见我在这里使用它(对我很羞耻)并因为这里没有父子关系来使用$scope。其他可能的解决方案:

  • 重新构建您的应用,以便您的组件可以相互通信。
  • 使用您自己的或第三方pub子库,以便您的组件可以相互通信。

希望这有帮助。

答案 1 :(得分:1)

https://plnkr.co/edit/5A5YFEWZ7ZTzRJloxgka?p=preview

我终于能够通过在标签$状态对象中使用命名视图来解决此问题。

const tags = {
  name: 'tags',
  url: '/tags',
  parent: 'dashboard',
  params: {
    counter: 0
  },
  views: {
    'default' : { template: '<p>Hi this is Tags</p>' },
    'title' : {
      template: '<p>Tags Title! {{ number }}</p>',
      controller: function($scope, $state) {
        $scope.number = Math.random();
      }
    },
    'counter': {
      template: '<p class="counter">Counter:{{ counter }}</p>',
      bindToController: true,
      controller: function($scope, $state) {
        console.log('tags state object', $state);
        $scope.counter = $state.params.counter;
      }
    }
  }
}

$stateProvider.state(tags);

现在使用这些命名视图,我可以使用具有特定名称的ui-view来定位来自tickers.component的更新计数器变量的位置。

params对象仍然与tags状态相关联,因此来自tickers的传入state.go将发送参数,但是标签的命名子视图现在将包含计数器。并且它不会在feed.component中流失到未命名或命名的ui视图。

标签模板html:

<div class="jumbotron text-center">
  <h2>Tags list</h2>
  <div ui-view="default"></div>

  <div class="row">
    <div>
      Tags title here:
      <div ui-view="title"></div>
    </div>

    <div>
      Tags counter here:
      <div ui-view="counter"></div>
    </div>
  </div>

</div>

tickers.component仍然以tags状态为目标并传递计数器变量。

$scope.increase = function() {
  $scope.counter++;
  $state.go('tags', { counter: $scope.counter });
}