我有两个与函数相关的变量,用户应该能够在输入字段中更改其中一个或另一个应该自动更改另一个的输入字段.
我怎么能这样做,现在我只是使用$watch.
JS,
angular.module("test",[]) .controller("MyController",function ($scope) { $scope.letter = 'A'; $scope.number = 1; $scope.map = { 'A': 1,'B': 2,'C': 3,'D': 4 }; $scope.$watch('letter',function(new_val,old_val){ if(new_val != old_val){ $scope.number = $scope.map[new_val]; } }); $scope.$watch('number',old_val){ ... }); });
HTML,
<div ng-app="test"> <div ng-controller="MyController"> <input ng-model="letter" /> <input type="number" ng-model="number" /> </div> </div>
解决方法
有很多方法可以做到这一点,使用$watch肯定是其中之一.正如Matt所提到的,您还可以使用ng-change指令在控制器上触发方法.
我想提供的第三种方法是使用ES5 properties和Angular在1.2中引入的Controller ‘as’ syntax
如果将控制器定义为JS对象而不是使用匿名函数,则可以向原型添加属性和方法:
myController = function () { this.map = {'A': 1,'D': 4}; this._letter = 'A'; this._number = 1; };
现在我们可以提取您已经完成的工作,将您的字母和数字值转换为函数:
myController.prototype.getLetterValue = function (num) { for (var key in this.map) { if (this.map.hasOwnProperty(key)) { if (this.map[key] === num) { return key; } } } }; myController.prototype.getNumberValue = function (letter) { return this.map[letter]; };
最后,我们将在您的控制器上声明一些使用Object.defineProperty
封装所需功能的属性.
Object.defineProperty( myController.prototype,"letter",{ get: function () { return this._letter; },set: function (newValue) { this._letter = newValue; this._number = this.getNumberValue(this._letter); },enumerable: true,configurable: true }); Object.defineProperty( myController.prototype,"number",{ get: function () { return this._number; },set: function (newValue) { this._number = newValue; this._letter = this.getLetterValue(this._number); },configurable: true });
将此控制器添加到您的模块:
angular.module("test",[]) .controller("MyController",myController);
最后,您只需稍微修改绑定语法,以便将新的Controller’用作’语法.这将允许您直接绑定到控制器上的属性和方法,而不必使用$scope
<div ng-app="test"> <div ng-controller="MyController as ctrl"> <input ng-model="ctrl.letter" /> <input type="number" ng-model="ctrl.number" /> </div> </div>
这不是完全没有代码,但确实有几个优点.
>您的控制器与$scope和$watch脱钩,使其更具便携性>控制器代码更易于阅读,因为所有功能都没有嵌套在匿名函数中>代码更具前瞻性,因为Angular的未来版本可能会通过使用本机observable来完全消除$scope和$digest循环.