简体   繁体   中英

prevent reflecting ng-model value across all select tags

I am pretty new to AngularJS. I am working on a project wherein I need to append certain html select tags based on a button click. Each select tag is bound to a ng-model attribute (which is hardcoded). Now the problem I am facing is, once I append more than 2 such html templates and make changes in a select tag then value selected is reflected across all the tags bound to the corresponding ng-model attribute (which is pretty obvious). I would like to know if there is a way around it without naming each ng-model differently.

JS code:

EsConnector.directive("placeholderid", function($compile, $rootScope, queryService, chartOptions){

 return {
 restrict : 'A',
 scope : true,


 link : function($scope, element, attrs){

$scope.current_mount1 = "iscsi";
$scope.current_dedupe1 = "on";
$scope.y_axis_param1 = "Total iops";
var totalIops =[];
var totalBandwidth =[];

    element.bind("click", function(){




        $scope.count++;
        $scope.placeholdervalue = "placeholder12"+$scope.count;




        var compiledHTML = $compile('<span class="static" id='+$scope.placeholdervalue+'>choose mount type<select ng-bind="current_mount1" ng-options="o as o for o in mount_type"></select>choose dedupe<select ng-model="current_dedupe1" ng-options="o as o for o in dedupe"></select>choose y axis param<select ng-model="y_axis_param1" ng-options="o as o for o in y_axis_param_options"></select></span><div id='+$scope.count+' style=width:1400px;height:300px></div>')($scope);


        $("#space-for-buttons").append(compiledHTML);

        $scope.$apply();




    $(".static").children().each(function() {


            $(this).on("change", function(){
            var id = $(this).closest("span").attr("id");

            var chartId = id.slice(-1);


            queryService.testing($scope.current_mount1, $scope.current_dedupe1, function(response){
            var watever = response.hits.hits;

            dataToBePlot = chartOptions.calcParams(watever, totalIops, totalBandwidth, $scope.y_axis_param1);

            chartOptions.creatingGraph(dataToBePlot, $scope.y_axis_param1, chartId);


        });




            });

    });

    });
}
 }

   });

Code explanation: This is just the directive which I am posting.I am appending my compiledHTML and doing $scope.apply to set the select tags to their default values. Whenever any of the select tags are changed I am doing a set of operations (function calls to services) on the values selected.

As you can see the ng-model attribute being attached is the same. So when one select tag is changed the value is reflected on all the appended HTML even though the data displayed does not match to it.

Hope this PLunker is useful for you. You need to have one way binding over such attributes

<p>Hello {{name}}!</p> 
<input ng-model="name"/>
<br>Single way binding: {{::name}}

Let me know if I misunderstood your question

It is a bit hard to understand your whole requirement from your description and your code, correct me if I'm wrong: you are trying to dynamically add a dropdown on a button click and then trying to keep track on each of them.

If you are giving the same ng-model for each generated items, then they are bound to the same object, and their behavior is synchronized, that is how angular works.

What you can do is, change your structure to an array, and then assigning ng-model to the elements, so you can conveniently keep track on each of them. I understand you came from jquery base on your code, so let me show you the angular way of doing things.

 angular.module('test', []).controller('Test', Test); function Test($scope) { $scope.itemArray = [ { id: 1, selected: "op1" }, { id: 2, selected: "op2" } ]; $scope.optionList = [ { name: "Option 1", value: "op1" }, { name: "Option 2", value: "op2" }, { name: "Option 3", value: "op3" } ] $scope.addItem = function() { var newItem = { id: $scope.itemArray.length + 1, selected: "" }; $scope.itemArray.push(newItem); } $scope.changeItem = function(item) { alert("changed item " + item.id + " to " + item.selected); } } 
 select { display: block; } 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script> <div ng-app='test' ng-controller='Test'> <button type='button' ng-click='addItem()'>Add</button> <select ng-repeat='item in itemArray' ng-options='option.value as option.name for option in optionList' ng-model='item.selected' ng-change='changeItem(item)'></select> </div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM