在 Angularjs 组件之间共享数据

Posted

技术标签:

【中文标题】在 Angularjs 组件之间共享数据【英文标题】:Sharing data between Angularjs components 【发布时间】:2018-03-05 11:32:22 【问题描述】:

我正在尝试重构 Angularjs 1.4 webapp 以使用组件。 该网络应用有一个带有“搜索”输入框的标题:主要部分显示了根据在搜索输入文本中输入的值过滤的联系人列表。 我正在尝试使用 ui-router(从列表切换到详细信息。我创建了 Header 和 Index 组件,定义了一个存储搜索值的服务,定义了一个带有“resolve”的状态 app.index 调用服务。 问题是在加载状态时解析只完成一次,而我想更新每个 jeypress 的过滤。 在我的代码中,我已经在父组件和标题之间绑定了搜索模型,因此我可以在每个模板中创建重复标题组件的组件,我认为它会起作用,但我想知道是否有更优雅的方法来做到这一点(信号不是很优雅,你不这么认为吗?) 这是我的 应用程序.html

<header-cnt-component search="$ctrl.search"></header-cnt-component>
<ui-view> </ui-view>

App.js

angular
  .module('app')
  .component('app', 
    templateUrl: 'app/containers/App.html',
    controller: App
  );

function App()  
  this.search = ;

HeaderCnt.html

<nav class="navbar navbar-default" role="navigation">
    <div class="collapse navbar-collapse" id="nav-toggle">
        <form class="navbar-form navbar-right" role="search">
            <input type="text" class="form-control" placeholder="Search" ng-model="$ctrl.search.name" ng-keyup="$ctrl.startSearch()">
        </form>
    </div>
</nav>

HeaderCnt.js

angular
  .module('app')
  .component('headerCntComponent', 
    templateUrl: 'app/components/HeaderCnt.html',
    controller: HeaderCnt,
    bindings: 
      search: '='
    
  );

  /** @ngInject */
function HeaderCnt(contactsService, searchService, $location) 
  this.contactsService = contactsService;
  this.searchService = searchService;
  this.location = $location;
  this.contacts = contactsService.get();


HeaderCnt.prototype = 

  startSearch: function () 
    this.searchService.set(this.search);
    this.location.path('/');
  
;

索引.html

<div class="table-responsive">
    <table class="table table-striped">
        <thead>
            <tr>
                <th>Name</th>
                <th>Email Address</th>
                <th>Phone Number</th>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="contact in $ctrl.contacts | filter:$ctrl.search">
                <td>contact.name</td>
                <td>contact.email</td>
                <td>contact.phone</td>
            </tr>
        </tbody>
    </table>
</div>

索引.js

angular
  .module('app')
  .component('indexComponent', 
    templateUrl: 'app/components/Index.html',
    controller: Index,
    bindings: 
      search: '='
    
  );

/** @ngInject */
function Index(contactsService) 
  this.contactsService = contactsService;
  this.contacts = contactsService.get();


Index.prototype = 
;

搜索.js

function SearchService() 
   var search = ;

   this.get = function () 
     return search;
   ;
   this.set = function (searchData) 
     search = searchData;
   ;
 

route.js

angular
  .module('app')
  .config(routesConfig);

/** @ngInject */
function routesConfig($stateProvider, $urlRouterProvider, $locationProvider) 
  $locationProvider.html5Mode(true).hashPrefix('!');
  $urlRouterProvider.otherwise('/');

  $stateProvider
    .state('app', 
      component: 'app'
    )
    .state('app.index', 
      url: '/',
      component: 'indexComponent',
      resolve: 
        search: function (searchService) 
          // var search = ;
          // search.name = 'aus';
          return searchService.get();
          // return search;
        
      
    );

【问题讨论】:

【参考方案1】:

如果我的理解正确,这可能会有所帮助。 我会为搜索添加新状态:

.state('app.index.search', 
      url: '/search/:searchString',
      component: 'indexComponent',
      resolve: 
        search: $stateParams => $stateParams.searchString
        
      
    )

如果你在 indexComponent 中绑定了搜索,rest 应该是相当简单的。

/搜索/一些用户搜索

将使用搜索字符串解析您的状态,如果您想在控制器上切换到特定的 searchString 状态,您可以使用:

$state.go('app.index.search', searchString)

还有一件事,您可以使用 ng-model-options=debounce: 500 来获得输入后的延迟(0.5 秒)并将观察者放在控制器上以更改模型。

所以你的 html 用于输入:

<input type="text" class="form-control" placeholder="Search" ng-model="$ctrl.search.name" ng-model-options="debounce: 500"/>

在控制器中:

this.$scope.$watch('$ctrl.search.name', (newVal, oldVal) => 
  newVal && $state.go('app.index.search', newVal');
);

如果有帮助,请告诉我。

【讨论】:

感谢您的回答!我尝试了您建议的第一部分:参数未传递给控制器​​...

以上是关于在 Angularjs 组件之间共享数据的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS:为啥人们更喜欢工厂在控制器之间共享数据[重复]

在 AngularJS 控制器之间共享数据

如何在 AngularJS 中的两个模块之间共享数据?

在 AngularJS 控制器之间共享数据? [复制]

在 AngularJS 中的两个指令之间共享数据

如何在 angularjs ui-router 中的状态之间共享 $scope 数据?