试图使用$ scope。$ watch with controllerAs

时间:2015-12-31 05:05:51

标签: javascript angularjs

我正在使用AngularJS构建状态自动完成

html似乎没有响应$ scope。$ watch,即使我可以通过console.log看到this.filteredStates最初被分配到状态,然后在输入中输入内容时更改。有什么遗漏?

angular.module('stateAutocomplete', [])
  .controller('stateAutocompleteCtrl', function($scope) {


    var states = ["Alabama", "Alaska", "American Samoa", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "District Of Columbia", "Federated States Of Micronesia", "Florida", "Georgia", "Guam", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Marshall Islands", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Northern Mariana Islands", "Ohio", "Oklahoma", "Oregon", "Palau", "Pennsylvania", "Puerto Rico", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virgin Islands", "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming"];

    this.filteredStates = [];

    $scope.$watch(angular.bind(this, function() {
        return this.input;
      }), function(newVal, oldVal) {
        if (newVal === oldVal) {
          this.filteredStates = states;
        } else {
          this.filteredStates = states.filter(function(state) {
            state = state.toLowerCase();
            var lowerCaseInput = newVal.toLowerCase();
            return state.indexOf(lowerCaseInput) > -1;
          })
        }
    })
  }) 




<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <link rel="stylesheet" href="styles.css">
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body ng-app="stateAutocomplete">
  <div  ng-controller="stateAutocompleteCtrl as state" class="container">
    <input ng-model="state.input" class="autocomplete"></input>
    <ul ng-repeat="state in state.filteredStates">
      <li>{{state}}</li>
    </ul>
  </div>
  <script src="app.js"></script>
</body>

1 个答案:

答案 0 :(得分:4)

问题是您忘记绑定$ watch中的第二个函数。以下代码有效; (但很难看)

angular.module('stateAutocomplete', [])
  .controller('stateAutocompleteCtrl', function($scope) {
    var states = ["Alabama", "Alaska", "American Samoa", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "District Of Columbia", "Federated States Of Micronesia", "Florida", "Georgia", "Guam", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Marshall Islands", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Northern Mariana Islands", "Ohio", "Oklahoma", "Oregon", "Palau", "Pennsylvania", "Puerto Rico", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virgin Islands", "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming"];

    this.filteredStates = [];

    $scope.$watch(
      angular.bind(this, function () { 
        return this.input; 
      }), 
      angular.bind(this, function(newVal, oldVal) {
        if (newVal === oldVal) {
          this.filteredStates = states;
        } else {
          this.filteredStates = states.filter(function(state) {
            state = state.toLowerCase();
            var lowerCaseInput = newVal.toLowerCase();
            return state.indexOf(lowerCaseInput) > -1;
          });
        }
      })
    );
  });

将变量绑定到控制器的更好方法是引入一个&#34; vm&#34;闭包内的变量,如下所示:(有关&#34的更好解释;为什么&#34;,请参阅例如:http://www.johnpapa.net/angularjss-controller-as-and-the-vm-variable/

angular.module('stateAutocomplete', [])
  .controller('stateAutocompleteCtrl', function($scope) {
    var vm = this;

    var states = ["Alabama", "Alaska", "American Samoa", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "District Of Columbia", "Federated States Of Micronesia", "Florida", "Georgia", "Guam", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Marshall Islands", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Northern Mariana Islands", "Ohio", "Oklahoma", "Oregon", "Palau", "Pennsylvania", "Puerto Rico", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virgin Islands", "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming"];

    vm.filteredStates = [];

    $scope.$watch(
      function () { 
        return vm.input; 
      }, 
      function (newVal, oldVal) {
        if (newVal === oldVal) {
          vm.filteredStates = states;
        } else {
          vm.filteredStates = states.filter(function (state) {
            state = state.toLowerCase();
            var lowerCaseInput = newVal.toLowerCase();
            return state.indexOf(lowerCaseInput) > -1;
          });
        }
      }
    );
  });