简体   繁体   中英

Using AngularJS watch to get drop-down's selected item not working

Following up from AngularJS : Why my watch is not working

function myController($scope, $http) {

    $scope.abc = abcValueFromOutsideOfMyController;    

    $scope.getAbcCnt= function()
    {
        url2 = baseURL + '/count/' + $scope.abc;

        $http.get(url2).success(function (data) {
            $scope.abcCnt = data.trim();
        });
    };

    $scope.$watch('abc',getAbcCnt);
}

Why I get undefined error on $scope.abc.

abcValueFromOutsideOfMyController is set by selecting element through a drop down. It will be undefined initially but as soon as dropdown is selected, the value will be something other than undefined, I verified in console, I get some value.

Drop down code is here

$(document).on('click', '.dropdown-menu li a', function () {

    selectedItem = $(this).text();
    $("#selectedItem").text(selectedItem);
    abcValueFromOutsideOfMyController= selectedItem.trim();
    console.log(abcValueFromOutsideOfMyController);
});

Here is my html

<div class="dropdown btn">

    <div id="collectiondropDown" class="dropdown-toggle" id="dLabel" role="button" data-toggle="dropdown"
         data-target="#" >
        &nbsp;<span id="selectedItem" ng-model="abc">Items</span>
        <b class="caret"></b>
    </div>

    <ul id="dropDownUL" class="dropdown-menu pull-left" role="menu" aria-labelledby="dLabel">
    </ul>
</div>

I am new to AngularJS, let me know if there is some fundamental concept I am missing and above is not possible to do.

$scope.abc , as you mention, is undefined at some point and is probably being accessed during this time. It looks like you're setting $scope.abc via jQuery, you should be doing it via the ng-model within AngularJS.

First, just define a stub for your variable:

$scope.abc = "";

Then in your HTML:

<input ... ng-model="abc" ... />

This will bind the input element (works on selections too) to the backend variable. As the user makes selections it will magically update in your code, and if you update the variable in your code it will update in the view too!

You can read more about ng-model here: http://docs.angularjs.org/api/ng.directive:ngModel

UPDATE

Here is another option that works with Twitter Bootstrap's Dropdown. It might not be the most "best" solution, but it is the first one that came to mind.

In your elements, you can add an ng-click directive and call a function in your controller. That controller then sets a variable that is used as the title for the button. In that case you don't use ng-model , you just include the variable in a {{ }} container.

Your HTML would look something like:

<div class="dropdown btn">
  <div id="collectiondropDown" class="dropdown-toggle" id="dLabel" role="button" data-toggle="dropdown" data-target="#" >
    <span>{{ selectedItem }}</span>
    <b class="caret"></b>
  </div>

  <ul id="dropDownUL" class="dropdown-menu pull-left" role="menu" aria-labelledby="dLabel">
    <li ng-click="OnItemClick('Option 1')">Option 1</li>
    <li ng-click="OnItemClick('Option 2')">Option 2</li>
    <li ng-click="OnItemClick('Option 3')">Option 3</li>
  </ul>
</div>

... and your JavaScript:

function DropdownCtrl($scope) {

  $scope.selectedItem = "Items";

  $scope.OnItemClick = function(event) {
    $scope.selectedItem = event;
  }
}

I've created a Plunker of the example. You can find it here: http://plnkr.co/edit/JrKJKxfG6aYiLHfR4pGE?p=preview

I have found an even better solution This is by far the simplest and least code solutions

 <ul id="dropDownUL" class="dropdown-menu pull-left" role="menu" aria-labelledby="dLabel">
   <li ng-click="abc = 'value1'">Value1</li>
   <li ng-click="abc = 'value2'">Value2</li>
 </ul>

There is also another way if you are loading them dynamically

  <ul id="dropDownUL" class="dropdown-menu pull-left" role="menu" aria-labelledby="dLabel">
   <li ng-repeat="value in values" ng-click="abc = value">{{value}}</li>
  </ul>

Notice the single ticks if its a static string value and no ticks if its dynamic.

I am able to get the selected item from the dropdown like below:

<body ng-app="app" ng-controller="ctrl">
<p>Id:{{id}}</p>
<select ng-model="id" ng-options="val.id as val.name for val in options">
</select>
<script>
angular.module("app",[])
  .controller("ctrl",['$scope',function($scope){
    $scope.options = [
      {id:1, name:'First'},
      {id:2, name:'Second'}
    ]
    $scope.$watch('id');
  }])
 </script>
</body>

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