Angular Material. Dynamically add a tab and go to that tab.

Currently working on a chat application here https://playwithfire.firebaseapp.com/ , and whenever a user adds a new room, I want a new room tab to be introduced. Currently you can add a room, but after that you need to click it to enter this room and display its contents.

I tried to change the md-selected = "selectedIndex" attribute, but it does not activate the tab, so the content does not appear.

Is it possible to do what I ask? What I have so far:

index.html

<div layout="column" ng-controller="RoomController"> <!-- Tabs Container --> <md-tabs md-stretch-tabs md-selected="selectedIndex"> <!-- Individual Tab --> <md-tab ng-repeat="room in roomList" label="{{room.roomName}}"> <div ng-controller="ChatController"> <!-- Display messages --> <md-list> <md-item ng-repeat="msg in messages"> <md-item-content> <div class="md-tile-content"> <div class="bubble"> <strong>{{msg.from}}</strong><br> {{msg.body}} </div> </div> </md-item-content> </md-item> </md-list><!--/DisplayMessages--> <!-- Chat controls --> <div layout="row" layout-margin layout-wrap> <div flex="33"> <!-- Assign username --> <label for="nameInput">Username</label> <input ng-model="name" type="text" id="nameInput" placeholder="Enter a username..."> </div> <div flex="95"> <!-- Post a message --> <label>Message</label> <textarea class="form-control" ng-model="msg" ng-keydown="addMessage($event)" id="messageInput" placeholder="Type a message..."> </textarea> </div> <div layout="row" layout-sm="column" layout-margin layout-fill layout-align="start end"> <!-- Click to send message --> <div flex> <md-button class="md-raised md-primary pull-left" ng-click="sendMessage()">Send</md-button> </div> <!-- Modal to add or join room --> <div flex ng-controller="ModalController"> <md-button class="md-raised md-primary pull-left" ng-click="open()">Add or Join Room</md-button> </div> <!-- Opens helper --> <div flex ng-controller="HelpController"> <md-button class="pull-right" ng-click="open()" ng-href="">Need help?</md-button> </div> </div> </div><!--/ChatController--> </md-tab> </md-tabs><!--/tabs container--> </div><!--/RoomController--> 

room.js

 angular.module('myApp') .controller('RoomController', function($scope, ShareFactory) { $scope.roomList = ShareFactory.roomList; // use this to default to index 0 in roomList $scope.selectedIndex = 0; $scope.$on('RoomChange', function(event, data) { $scope.selectedIndex = data; console.log('Heard the change!'); console.log('The data is: ' + data); }); }); 

modal.js

 angular.module('myApp') .controller('ModalController', function($rootScope, $scope, $modal, ChatFactory, ShareFactory) { $scope.open = function () { var modalInstance = $modal.open({ templateUrl: 'views/modal.html', controller: 'ModalInstanceController' }); modalInstance.result.then(function (name) { var found = false; var length = ShareFactory.roomList.length; var index = 0; for(var i = 0; i < length; ++i) { if(ShareFactory.roomList[i].roomName === name) { found = true; index = i; console.log('index ' + index); } } if(!found) { ShareFactory.roomList.push({ roomName : name}); index = ShareFactory.roomList.length - 1; } else { // don't care about disabled, not a feature i want to use //ShareFactory.roomList[index].disabled = false; } // Broadcast event to all children of rootScope // namely want RoomController to listen for this change $rootScope.$broadcast('RoomChange', index); }, function () { console.log('cancel'); }); }; }); 
+6
source share
1 answer

I know this definitely appeared in the Github issue some time ago, but it may have been thrown off due to other high priority issues.

I just added this function for mastering: https://github.com/angular/material/commit/8285e2d0bb6efbc72e311ee85b619cbbe8437072

And this should be available for viewing on our website in the second demo: https://material.angularjs.org/HEAD/#/demo/material.components.tabs

In the meantime, you can solve this problem by adding the following code:

 if(!found) { ShareFactory.roomList.push({ roomName : name}); index = ShareFactory.roomList.length - 1; $timeout(function () { ShareFactory.selectedIndex = index; }); } 

$timeout necessary because you have to wait until after rendering is complete before you can update the selected index to a new one, otherwise it will assume that it is valid out of range.

Hope this helps!

+6
source

Source: https://habr.com/ru/post/984929/


All Articles