Search code examples
angularjsangularjs-scopeangular-directive

How to design angular app with multiple models and select fields


What I'm trying to build is a SPA containing multiple selects on one page, where each select has it's own model. Choosing different options in the select boxes may show/hide other fields on the page and modify data for other selects (load different sets). Finally options in two selects may change the url (so when page is loaded with a proper address, those two options will be preselected). Now I'm wondering what'll be the best approach here.

First. Is it worth to switch to ui-router in this case ?

Second. I need to write a custom directive for this select, that will have the following functionality

  1. load data collection
  2. display data and remember selection
  3. reload it's data collection when other select triggered it
  4. reload data for other selects

Now I've written directives before but never anything this (I think) complex. That's why few questions come to my mind.

How can I bind different data to my directive ? Should this be just a single massive complex directive or divide it to smaller parts (like one directive for showing closed select box and another one to show the list and so on) ? How can I trigger event when data should be changed and listen to a similar event from another select. Via controller ?

Thanks in advance for all your help.


Solution

  • What I can suggest is keep it MVC. Here is one of the solution -

    1. Create a controller to store model data (here $scope.selectOptions inside controller)
    2. Pass this values to 'select directive' instance to display
    3. Whenever user select the value in directive, pass that selected value to controller (lets say in controller $scope.selectedValue is holding that value)
    4. In controller add $watch on $scope.selectedValue and in its callback call for different data set for another select option. (lets say storing that data set in $scope.anotherSelectOption )
    5. Pass this $scope.anotherSelectOption to '2nd directive' instance
    6. Whenever user select the value in 2nd directive, pass that selected value to controller (lets say in controller $scope.anotherSelectedValue is holding that value)
    7. In controller add $watch on $scope.anotherSelectedValue and in its callback change url thing you want to do

    Here's your HTML will look like -

    <div ng-controller="MyCtrl">
        <select-directive selection-option="selectOptions", selected-option="selectedValue"> </select-directive>
        <select-directive selection-option="anotherSelectOptions", selected-option="anotherSelectedValue"> </select-directive>
    </div>
    

    Here's your controller, it will look something like this -

    yourApp.controller('MyCtrl', function($scope) {
    
        $scope.selectOptions = []; // add init objects for select 
        $scope.selectedValue = null;
    
        $scope.$watch('selectedValue', function() {
            // here load new values for $scope.anotherSelectOptions
            $scope.anotherSelectOptions = [] // add init objects for select 
            $scope.anotherSelectedValue = null;
        });
    
        $scope.$watch('anotherSelectedValue', function() {
            // here add code for change URL
        });
    
    });
    

    Here's your directive scope is

    yourApp.directive('selectDirective', function() {
        return {
            templateUrl: 'views/directives/select.html',
            restrict: 'E',
            scope: {
                selectionOption: '=',
                selectedOption: '='
            }
        };
    });