【问题标题】:ui-view for 1 module duplicating content from another module1 个模块的 ui-view 从另一个模块复制内容
【发布时间】:2017-03-16 16:11:09
【问题描述】:

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

预期

login 后,当您点击 Count 时,Tags 列表中的红色数字应该会发生变化并与 Tickers 列表中的数字匹配,但 Feed 列表中不会发生任何事情.

结果

登录后,点击Tickers列表中的Count,红色的数字同时出现在Tags列表和Feed列表中。


完整的 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 模块中的仪表板状态关联的仪表板.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)

  }
})

【问题讨论】:

  • 您是否尝试过将tagsfeed 添加到您的状态,就像dashboardlogin(带有名称、templateUrl 和不同的控制器)?然后,做ui-view="tags"ui-view="feed" 或类似的东西?
  • 我在某个时候尝试了ui-view="tags",但没有成功,但我希望将这些模块分开。最终目标是更改一个模块中的某些内容不一定会导致另一个模块刷新/重新初始化。
  • 这很奇怪。通常ui-view 没有值是指index.html...

标签: javascript angularjs angular-ui-router


【解决方案1】:

这是具有所需功能的 Plunker link

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

它以您描述的方式工作的原因是因为ui-router 正在做应该做的事情:)。

即使您尝试将模板加载分开到单独的模块中,但这并没有按您的计划进行。一旦dashboard 状态被加载,你的所有组件也被加载。 tags-modulefeed-module之所以同时更新,是因为它们各自的模板中都有ui-view。所以当你点击按钮并执行$state.go("tags"...时,你基本上已经在每个带有ui-view属性的组件中加载了tags状态模板。

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

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

希望这会有所帮助。

【讨论】:

  • 谢谢,使用事件是我们的应用在 6 个月前的样子。我们正在尝试仅使用 $state 和视图来完成此操作。您的答案有效,如果很快没有其他基于 $state/view 的答案,我会检查您的解决方案。但会继续尝试寻找 $state 方式。
  • 找到了解决办法!现在发布,您可以查看。
【解决方案2】:

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

我终于能够通过在 Tags $state 对象中使用命名视图来解决这个问题。

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 状态相关联,因此来自股票代码的传入 state.go 将发送参数,但是标签的命名子视图现在将包含计数器。而且它不会渗入 feed.component 中未命名或命名的 ui-view。

标签模板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 });
}

【讨论】:

  • 只要你只在tags-module模板中使用ui-view="title"ui-view="counter",就可以了。 :)
猜你喜欢
  • 1970-01-01
  • 2016-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多