0

I know I can filter like this:

<input type="search" ng-model="searchTable">
<table>
  <thead>
    <tr>
      <th>First Name</th>
      <th>Last Name</th>
    </tr>
  </thead>
  <tbody>
    <tr ng-repeat="row in $ctrl.rows | filter: searchTable">
      <td>{{ row.firstName }}</td>
      <td>{{ row.lastName }}</td>
    </tr>
  </tbody>
</table>

How do I filter if the <input type="search" ng-model="searchTable"> and <tr ng-repeat="row in $ctrl.rows | filter: searchTable"> are in separate components?

Here's a simple fiddle.

From what I understand I'll need to add an $onChanges() and expression binding bindings: { onChange: '&' } to the searchComponent, but don't fully understand how to implement it.

Thanks

2 Answers 2

3

Here is the working fiddle. You store the search term in parent component and pass it to both child components.

var app = angular.module('app', []);

app.controller('appController', function() {
	this.search = "";
});

app.component('searchComponent', {
	template: `
  	<h4>{{ $ctrl.title }}</h4>
    <label>Search table</label>
    <input type="search" ng-model="$ctrl.search">
  `,
  controller: function() {
  	this.title = 'Search Component';
  },
  bindings: {
  	search: "="
  }
});

app.component('tableComponent', {
	template: `
  	<h4>{{ $ctrl.title }}</h4>
    <!-- <p>This works</p> 
    <label>Search table</label>
    <input type="search" ng-model="searchTable"> -->
    <table>
    	<thead>
      	<tr>
        	<th>First Name</th>
          <th>Last Name</th>
        </tr>
      </thead>
    	<tbody>
      	<tr ng-repeat="row in $ctrl.rows | filter: $ctrl.search">
        	<td>{{ row.firstName }}</td>
          <td>{{ row.lastName }}</td>
        </tr>
      </tbody>
    </table>
  `,
  controller: function() {
 		this.title = 'Table Component';
    
    this.rows = [
    	{firstName: 'Zulu', lastName: 'Apple'},
      {firstName: 'Alice', lastName: 'xRay'},
      {firstName: 'Fred', lastName: 'Rogers'}
    ];
  },
  bindings: {
  	search: "<"
  }
});
body {
  font-family: 'Arial', sans-serif;
}
table {
  border-collapse: collapse;
}
td, th {
  border: 1px solid grey;
  padding: 5px;
}
label {
  display: block;
}
input {
  margin-bottom: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.0/angular.min.js"></script>
<div ng-app="app">
  <div ng-controller="appController">
    <h3>Filter Between Components</h3>
    <search-component search="search"></search-component>
    <table-component search="search"></table-component>
  </div>
</div>

Sign up to request clarification or add additional context in comments.

Comments

0

You can try emit - on in your component to communicate between as shown in the below code. Also please check your updated jsfiddle with working example of your given scenario.

Search Component Controller:

$scope.$watch('searchTable', function() {
  $rootScope.$emit('onEmitSearchData', $scope.searchTable);
});

Table Component Controller:

$rootScope.$on('onEmitSearchData', function(event, data) {
  $scope.searchTable = data;
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.